Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/misc/bitset.pyx
8814 views
1
r"""
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
inclusive (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 data structures, 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
#*****************************************************************************
20
# Copyright (C) 2009 Jason Grout <[email protected]>
21
#
22
# Distributed under the terms of the GNU General Public License (GPL)
23
#
24
# This code is distributed in the hope that it will be useful,
25
# but WITHOUT ANY WARRANTY; without even the implied warranty of
26
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27
# General Public License for more details.
28
#
29
# The full text of the GPL is available at:
30
#
31
# http://www.gnu.org/licenses/
32
#*****************************************************************************
33
34
include "bitset.pxi"
35
36
cdef class FrozenBitset:
37
r"""
38
A frozen bitset class which leverages inline Cython functions for
39
creating and manipulating bitsets.
40
41
A bitset can be thought of in two ways. First, as a set of elements
42
from the universe of the `n` natural numbers `0, 1, \dots, n-1` (where
43
the capacity `n` can be specified), with typical set operations such as
44
intersection, union, symmetric difference, etc. Secondly, a bitset can
45
be thought of as a binary vector with typical binary operations such as
46
``and``, ``or``, ``xor``, etc. This class supports both interfaces.
47
48
The interface in this class mirrors the interface in the ``frozenset``
49
data type of Python. See the Python documentation on `set types
50
<http://docs.python.org/library/stdtypes.html#set-types-set-frozenset>`_
51
for more details on Python's ``set`` and ``frozenset`` classes.
52
53
.. warning::
54
55
This class is most likely to be useful as a way to store
56
Cython bitsets in Python data structures, acting on them using
57
the Cython inline functions. If you want to use this class
58
for a Python set type, the Python ``frozenset`` data type may
59
be faster.
60
61
INPUT:
62
63
- ``iter`` -- initialization parameter (default: ``None``). Valid input
64
are:
65
66
- :class:`Bitset` and :class:`FrozenBitset` -- If this is a
67
:class:`Bitset` or :class:`FrozenBitset`, then it is copied.
68
69
- ``None`` -- If ``None``, then the bitset is set to the empty set.
70
71
- string -- If a nonempty string, then the bitset is initialized by
72
including an element if the index of the string is ``1``. If the
73
string is empty, then raise a ``ValueError``.
74
75
- iterable -- If an iterable, then it is assumed to contain a list of
76
nonnegative integers and those integers are placed in the set.
77
78
- ``capacity`` -- (default: ``None``) The maximum capacity of the bitset.
79
If this is not specified, then it is automatically calculated from the
80
passed iterable. It must be at least one.
81
82
OUTPUT:
83
84
- None.
85
86
The string representation of a :class:`FrozenBitset` ``FB`` can be
87
understood as follows. Let `B = b_0 b_1 b_2 \cdots b_k` be the string
88
representation of the bitset ``FB``, where each `b_i \in \{0, 1\}`. We
89
read the `b_i` from left to right. If `b_i = 1`, then the nonnegative
90
integer `i` is in the bitset ``FB``. Similarly, if `b_i = 0`, then `i`
91
is not in ``FB``. In other words, ``FB`` is a subset of
92
`\{0, 1, 2, \dots, k\}` and the membership in ``FB`` of each `i` is
93
determined by the binary value `b_i`.
94
95
.. seealso::
96
97
- :class:`Bitset`
98
99
- Python's `set types <http://docs.python.org/library/stdtypes.html#set-types-set-frozenset>`_
100
101
EXAMPLES:
102
103
The default bitset, which has capacity 1::
104
105
sage: FrozenBitset()
106
0
107
sage: FrozenBitset(None)
108
0
109
110
Trying to create an empty bitset fails::
111
112
sage: FrozenBitset([])
113
Traceback (most recent call last):
114
...
115
ValueError: Bitsets must not be empty
116
sage: FrozenBitset(list())
117
Traceback (most recent call last):
118
...
119
ValueError: Bitsets must not be empty
120
sage: FrozenBitset(())
121
Traceback (most recent call last):
122
...
123
ValueError: Bitsets must not be empty
124
sage: FrozenBitset(tuple())
125
Traceback (most recent call last):
126
...
127
ValueError: Bitsets must not be empty
128
sage: FrozenBitset("")
129
Traceback (most recent call last):
130
...
131
ValueError: Bitsets must not be empty
132
133
We can create the all-zero bitset as follows::
134
135
sage: FrozenBitset(capacity=10)
136
0000000000
137
sage: FrozenBitset([], capacity=10)
138
0000000000
139
140
We can initialize a :class:`FrozenBitset` with a :class:`Bitset` or
141
another :class:`FrozenBitset`, and compare them for equality. As they
142
are logically the same bitset, the equality test should return ``True``.
143
Furthermore, each bitset is a subset of the other. ::
144
145
sage: def bitcmp(a, b, c): # custom function for comparing bitsets
146
....: print(a == b == c)
147
....: print(a <= b, b <= c, a <= c)
148
....: print(a >= b, b >= c, a >= c)
149
....: print(a != b, b != c, a != c)
150
sage: a = Bitset("1010110"); b = FrozenBitset(a); c = FrozenBitset(b)
151
sage: a; b; c
152
1010110
153
1010110
154
1010110
155
sage: a < b, b < c, a < c
156
(False, False, False)
157
sage: a > b, b > c, a > c
158
(False, False, False)
159
sage: bitcmp(a, b, c)
160
True
161
(True, True, True)
162
(True, True, True)
163
(False, False, False)
164
165
Try a random bitset::
166
167
sage: a = Bitset(randint(0, 1) for n in range(1, randint(1, 10^4)))
168
sage: b = FrozenBitset(a); c = FrozenBitset(b)
169
sage: bitcmp(a, b, c)
170
True
171
(True, True, True)
172
(True, True, True)
173
(False, False, False)
174
175
A bitset with a hard-coded bitstring::
176
177
sage: FrozenBitset('101')
178
101
179
180
For a string, only those positions with ``1`` would be initialized to ``1``
181
in the corresponding position in the bitset. All other characters in the
182
string, including ``0``, are set to ``0`` in the resulting bitset. ::
183
184
sage: FrozenBitset('a')
185
0
186
sage: FrozenBitset('abc')
187
000
188
sage: FrozenBitset('abc1')
189
0001
190
sage: FrozenBitset('0abc1')
191
00001
192
sage: FrozenBitset('0abc10')
193
000010
194
sage: FrozenBitset('0a*c10')
195
000010
196
197
Represent the first 10 primes as a bitset. The primes are stored as a
198
list and as a tuple. We then recover the primes from its bitset
199
representation, and query the bitset for its length (how many elements
200
it contains) and whether an element is in the bitset. Note that the
201
length of a bitset is different from its capacity. The length counts
202
the number of elements currently in the bitset, while the capacity
203
is the number of elements that the bitset can hold. ::
204
205
sage: p = primes_first_n(10); p
206
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
207
sage: tuple(p)
208
(2, 3, 5, 7, 11, 13, 17, 19, 23, 29)
209
sage: F = FrozenBitset(p); F; FrozenBitset(tuple(p))
210
001101010001010001010001000001
211
001101010001010001010001000001
212
213
Recover the primes from the bitset::
214
215
sage: for b in F:
216
....: print b,
217
2 3 5 7 11 13 17 19 23 29
218
sage: list(F)
219
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
220
221
Query the bitset::
222
223
sage: len(F)
224
10
225
sage: len(list(F))
226
10
227
sage: F.capacity()
228
30
229
sage: s = str(F); len(s)
230
30
231
sage: 2 in F
232
True
233
sage: 1 in F
234
False
235
236
A random iterable, with all duplicate elements removed::
237
238
sage: L = [randint(0, 100) for n in range(1, randint(1, 10^4))]
239
sage: FrozenBitset(L) == FrozenBitset(list(set(L)))
240
True
241
sage: FrozenBitset(tuple(L)) == FrozenBitset(tuple(set(L)))
242
True
243
244
TESTS:
245
246
Loading and dumping objects::
247
248
sage: a = FrozenBitset('1101')
249
sage: loads(dumps(a)) == a
250
True
251
sage: a = FrozenBitset('1101' * 64)
252
sage: loads(dumps(a)) == a
253
True
254
255
If ``iter`` is a nonempty string and ``capacity`` is specified, then
256
``capacity`` must match the number of elements in ``iter``::
257
258
sage: FrozenBitset("110110", capacity=3)
259
Traceback (most recent call last):
260
...
261
ValueError: bitset capacity does not match passed string
262
sage: FrozenBitset("110110", capacity=100)
263
Traceback (most recent call last):
264
...
265
ValueError: bitset capacity does not match passed string
266
267
The parameter ``capacity`` must be positive::
268
269
sage: FrozenBitset("110110", capacity=0)
270
Traceback (most recent call last):
271
...
272
ValueError: bitset capacity must be greater than 0
273
sage: FrozenBitset("110110", capacity=-2)
274
Traceback (most recent call last):
275
...
276
OverflowError: can't convert negative value to unsigned long
277
"""
278
def __cinit__(self, iter=None, capacity=None):
279
"""
280
Allocate the bitset.
281
282
See the class documentation of :class:`FrozenBitset` for details
283
on the parameters.
284
285
EXAMPLES::
286
287
sage: FrozenBitset('1101')
288
1101
289
sage: FrozenBitset('1101' * 32)
290
11011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101
291
"""
292
if capacity is None:
293
bitset_init(self._bitset, 1)
294
else:
295
bitset_init(self._bitset, capacity)
296
297
def __dealloc__(self):
298
"""
299
Deallocate the C bitset data structure.
300
301
EXAMPLES::
302
303
sage: a = FrozenBitset('11010')
304
sage: del a
305
sage: b = FrozenBitset('11010' * 64)
306
sage: del b
307
"""
308
bitset_free(self._bitset)
309
310
def __init__(self, iter=None, capacity=None):
311
"""
312
Initialize a bitset.
313
314
See the class documentation of ``FrozenBitset`` for details on the
315
parameters.
316
317
EXAMPLES::
318
319
sage: FrozenBitset(capacity=3)
320
000
321
sage: FrozenBitset('11011')
322
11011
323
sage: FrozenBitset('110' * 32)
324
110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110
325
sage: FrozenBitset([0,3,2])
326
1011
327
sage: FrozenBitset(set([0,3,2]))
328
1011
329
sage: FrozenBitset(FrozenBitset('11011'))
330
11011
331
sage: FrozenBitset([0,3,2], capacity=10)
332
1011000000
333
sage: FrozenBitset([i for i in range(100) if i % 2 == 0])
334
101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
335
336
TESTS:
337
338
The capacity must be at least one::
339
340
sage: FrozenBitset()
341
0
342
343
If capacity is specified, it must match up with the
344
initialization items::
345
346
sage: FrozenBitset('10', capacity=3)
347
Traceback (most recent call last):
348
...
349
ValueError: bitset capacity does not match passed string
350
sage: FrozenBitset([0,3,2], capacity=2)
351
Traceback (most recent call last):
352
...
353
ValueError: bitset capacity does not allow storing the passed iterable
354
sage: FrozenBitset(FrozenBitset('1101'), capacity=2)
355
Traceback (most recent call last):
356
...
357
ValueError: bitset capacity does not match passed bitset
358
sage: FrozenBitset(FrozenBitset('1101'), capacity=5)
359
Traceback (most recent call last):
360
...
361
ValueError: bitset capacity does not match passed bitset
362
"""
363
cdef unsigned long n
364
cdef FrozenBitset b
365
if iter is not None and not isinstance(iter, (str, tuple, list, FrozenBitset, Bitset)):
366
iter = list(iter)
367
368
if iter is None:
369
bitset_clear(self._bitset)
370
elif isinstance(iter, (FrozenBitset, Bitset)):
371
b = iter
372
if capacity is None:
373
bitset_realloc(self._bitset, b._bitset.size)
374
elif self._bitset.size != b._bitset.size:
375
raise ValueError("bitset capacity does not match passed bitset")
376
bitset_copy(self._bitset, b._bitset)
377
elif isinstance(iter, str):
378
if len(iter) == 0:
379
raise ValueError("Bitsets must not be empty")
380
if capacity is None:
381
bitset_realloc(self._bitset, len(iter))
382
elif self._bitset.size != len(iter):
383
raise ValueError("bitset capacity does not match passed string")
384
bitset_from_str(self._bitset, iter)
385
else: # an iterable
386
iter = list(iter)
387
if len(iter) > 0:
388
need_capacity = max(iter) + 1
389
else:
390
need_capacity = 0
391
if capacity is None:
392
if need_capacity == 0:
393
raise ValueError("Bitsets must not be empty")
394
bitset_realloc(self._bitset, need_capacity)
395
elif self._bitset.size < need_capacity:
396
raise ValueError("bitset capacity does not allow storing the passed iterable")
397
bitset_clear(self._bitset)
398
for n in iter:
399
bitset_add(self._bitset, n)
400
401
cdef FrozenBitset _new(self, long int capacity):
402
r"""
403
Return an object of the same type as ``self``, initialized with a
404
bitset of capacity ``capacity``.
405
"""
406
cdef FrozenBitset b
407
b = FrozenBitset.__new__(FrozenBitset, None, capacity)
408
return b
409
410
def __getstate__(self):
411
"""
412
Return the current state of the object as a string.
413
414
EXAMPLES::
415
416
sage: FrozenBitset('1101').__getstate__()
417
'1101'
418
sage: FrozenBitset('110'*32).__getstate__()
419
'110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110'
420
"""
421
return str(self)
422
423
def __setstate__(self, state):
424
"""
425
Set the state of the object from the string state.
426
427
EXAMPLES::
428
429
sage: a = FrozenBitset()
430
sage: a.__setstate__('1101')
431
sage: a
432
1101
433
sage: a.__setstate__('110'*32)
434
sage: a
435
110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110
436
"""
437
bitset_realloc(self._bitset, len(state))
438
bitset_from_str(self._bitset, state)
439
440
def __iter__(self):
441
"""
442
Return an iterator over ``self``.
443
444
EXAMPLES::
445
446
sage: list(FrozenBitset('11011'))
447
[0, 1, 3, 4]
448
sage: list(FrozenBitset('00001' * 20))
449
[4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79, 84, 89, 94, 99]
450
sage: set(FrozenBitset('11011'))
451
set([0, 1, 3, 4])
452
"""
453
return iter(bitset_list(self._bitset))
454
455
cpdef FrozenBitset _larger_capacity_(self, long capacity):
456
"""
457
Return a copy of ``self`` where the bitset has the maximum of the
458
current capacity and the capacity passed. If no resizing is needed,
459
return ``self``.
460
461
This function is mainly used to satisfy the assumption of the
462
underlying bitset functions that all bitsets are of the same
463
capacity.
464
465
INPUT:
466
467
- ``capacity`` -- the underlying bitset of the returned bitset
468
will have this capacity if it is bigger than the current
469
capacity.
470
471
EXAMPLES::
472
473
sage: a = FrozenBitset('11010')
474
sage: a.capacity()
475
5
476
sage: a._larger_capacity_(4) is a
477
True
478
sage: a._larger_capacity_(5) is a
479
True
480
sage: b = a._larger_capacity_(6)
481
sage: b
482
110100
483
sage: b is a
484
False
485
sage: b.capacity()
486
6
487
sage: c = a._larger_capacity_(98)
488
sage: c
489
11010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
490
sage: c.capacity()
491
98
492
"""
493
cdef FrozenBitset temp
494
if self._bitset.size >= capacity:
495
return self
496
else:
497
temp = self._new(self._bitset.size)
498
bitset_copy(temp._bitset, self._bitset)
499
bitset_realloc(temp._bitset, capacity)
500
return temp
501
502
cpdef long capacity(self):
503
"""
504
Return the size of the underlying bitset.
505
506
The maximum value that can be stored in the current underlying
507
bitset is ``self.capacity() - 1``.
508
509
EXAMPLES::
510
511
sage: FrozenBitset('11000').capacity()
512
5
513
sage: FrozenBitset('110' * 32).capacity()
514
96
515
sage: FrozenBitset(range(20), capacity=450).capacity()
516
450
517
"""
518
return self._bitset.size
519
520
def __hash__(self):
521
"""
522
Return a hash value for a bitset.
523
524
EXAMPLES::
525
526
sage: hash(FrozenBitset(capacity=5))
527
0
528
sage: hash(FrozenBitset('10110'))
529
13
530
sage: hash(FrozenBitset('10110' + '0' * 120, capacity=125))
531
13
532
"""
533
cdef long hash
534
hash = bitset_hash(self._bitset)
535
if hash == -1:
536
return 0
537
else:
538
return hash
539
540
cpdef bint isempty(self):
541
"""
542
Test if the bitset is empty.
543
544
INPUT:
545
546
- None.
547
548
OUTPUT:
549
550
- ``True`` if the bitset is empty; ``False`` otherwise.
551
552
EXAMPLES::
553
554
sage: FrozenBitset().isempty()
555
True
556
sage: FrozenBitset([1]).isempty()
557
False
558
sage: FrozenBitset([], capacity=110).isempty()
559
True
560
sage: FrozenBitset(range(99)).isempty()
561
False
562
"""
563
return bitset_isempty(self._bitset)
564
565
def __richcmp__(FrozenBitset self, FrozenBitset other not None, int op):
566
"""
567
Implement comparisons, using the Cython richcmp convention.
568
Comparison is done by inclusion. That is, a set ``A`` is less than
569
another set ``B``, written ``A < B``, if ``A`` is a subset of ``B``.
570
571
EXAMPLES::
572
573
sage: FrozenBitset('11') < FrozenBitset('101')
574
False
575
sage: FrozenBitset('11') <= FrozenBitset('110')
576
True
577
sage: FrozenBitset('11') != FrozenBitset('10')
578
True
579
sage: FrozenBitset('11') == FrozenBitset('10')
580
False
581
sage: FrozenBitset('11') == FrozenBitset('110')
582
True
583
sage: FrozenBitset('11') > FrozenBitset('10')
584
True
585
sage: FrozenBitset('11') >= FrozenBitset('10')
586
True
587
sage: FrozenBitset('11') < FrozenBitset('110' * 32)
588
True
589
590
TESTS:
591
592
When performing comparison, ``other`` cannot be ``None``. ::
593
594
sage: F = FrozenBitset('11')
595
sage: F < None
596
Traceback (most recent call last):
597
...
598
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
599
sage: F <= None
600
Traceback (most recent call last):
601
...
602
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
603
sage: F > None
604
Traceback (most recent call last):
605
...
606
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
607
sage: F >= None
608
Traceback (most recent call last):
609
...
610
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
611
sage: F == None
612
Traceback (most recent call last):
613
...
614
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
615
sage: F != None
616
Traceback (most recent call last):
617
...
618
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
619
sage: None < F
620
Traceback (most recent call last):
621
...
622
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
623
sage: None <= F
624
Traceback (most recent call last):
625
...
626
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
627
sage: None > F
628
Traceback (most recent call last):
629
...
630
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
631
sage: None >= F
632
Traceback (most recent call last):
633
...
634
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
635
sage: None == F
636
Traceback (most recent call last):
637
...
638
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
639
sage: None != F
640
Traceback (most recent call last):
641
...
642
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
643
"""
644
cdef FrozenBitset left, right
645
646
if self._bitset.size == other._bitset.size:
647
left = self
648
right = other
649
elif self._bitset.size < other._bitset.size:
650
left = self._larger_capacity_(other._bitset.size)
651
right = other
652
else:
653
left = self
654
right = other._larger_capacity_(self._bitset.size)
655
656
if op == 2: # ==
657
return bitset_eq(left._bitset, right._bitset)
658
elif op == 3: # !=
659
return not bitset_eq(left._bitset, right._bitset)
660
elif op == 0: # <
661
return bitset_issubset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
662
elif op == 1: # <=
663
return bitset_issubset(left._bitset, right._bitset)
664
elif op == 4: # >
665
return bitset_issuperset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
666
elif op == 5: # >=
667
return bitset_issuperset(left._bitset, right._bitset)
668
669
cpdef bint issubset(self, FrozenBitset other) except -1:
670
"""
671
Test to see if ``self`` is a subset of ``other``.
672
673
EXAMPLES::
674
675
sage: FrozenBitset('11').issubset(FrozenBitset('01'))
676
False
677
sage: FrozenBitset('01').issubset(FrozenBitset('11'))
678
True
679
sage: FrozenBitset('01').issubset(FrozenBitset('01' * 45))
680
True
681
682
TESTS::
683
684
sage: FrozenBitset('11').issubset(None)
685
Traceback (most recent call last):
686
...
687
ValueError: other cannot be None
688
"""
689
if other is None:
690
raise ValueError("other cannot be None")
691
cdef FrozenBitset left, right
692
if self._bitset.size == other._bitset.size:
693
left = self
694
right = other
695
elif self._bitset.size < other._bitset.size:
696
left = self._larger_capacity_(other._bitset.size)
697
right = other
698
else:
699
left = self
700
right = other._larger_capacity_(self._bitset.size)
701
702
return bitset_issubset(left._bitset, right._bitset)
703
704
cpdef bint issuperset(self, FrozenBitset other) except -1:
705
"""
706
Test to see if ``self`` is a superset of ``other``.
707
708
EXAMPLES::
709
710
sage: FrozenBitset('11').issuperset(FrozenBitset('01'))
711
True
712
sage: FrozenBitset('01').issuperset(FrozenBitset('11'))
713
False
714
sage: FrozenBitset('01').issuperset(FrozenBitset('10' * 45))
715
False
716
717
TESTS::
718
719
sage: FrozenBitset('11').issuperset(None)
720
Traceback (most recent call last):
721
...
722
ValueError: other cannot be None
723
"""
724
if other is None:
725
raise ValueError("other cannot be None")
726
cdef FrozenBitset left, right
727
if self._bitset.size == other._bitset.size:
728
left = self
729
right = other
730
elif self._bitset.size < other._bitset.size:
731
left = self._larger_capacity_(other._bitset.size)
732
right = other
733
else:
734
left = self
735
right = other._larger_capacity_(self._bitset.size)
736
737
return bitset_issuperset(left._bitset, right._bitset)
738
739
cpdef bint isdisjoint(self, FrozenBitset other) except -1:
740
"""
741
Test to see if ``self`` is disjoint from ``other``.
742
743
EXAMPLES::
744
745
sage: FrozenBitset('11').isdisjoint(FrozenBitset('01'))
746
False
747
sage: FrozenBitset('01').isdisjoint(FrozenBitset('001'))
748
True
749
sage: FrozenBitset('00101').isdisjoint(FrozenBitset('110' * 35))
750
False
751
752
TESTS::
753
754
sage: FrozenBitset('11').isdisjoint(None)
755
Traceback (most recent call last):
756
...
757
ValueError: other cannot be None
758
"""
759
cdef bint retval
760
if other is None:
761
raise ValueError("other cannot be None")
762
cdef FrozenBitset smaller, larger
763
cdef bitset_t temp
764
if self._bitset.size == other._bitset.size:
765
bitset_init(temp, self._bitset.size)
766
bitset_intersection(temp, self._bitset, other._bitset)
767
retval = bitset_isempty(temp)
768
bitset_free(temp)
769
return retval
770
elif self._bitset.size < other._bitset.size:
771
smaller = self
772
larger = other
773
else:
774
smaller = other
775
larger = self
776
777
bitset_init(temp, smaller._bitset.size)
778
bitset_copy(temp, smaller._bitset)
779
bitset_realloc(temp, larger._bitset.size)
780
bitset_intersection(temp, temp, larger._bitset)
781
retval = bitset_isempty(temp)
782
bitset_free(temp)
783
return retval
784
785
def __contains__(self, unsigned long n):
786
"""
787
Test to see if ``n`` is in ``self``.
788
789
EXAMPLES::
790
791
sage: 0 in FrozenBitset([0,1])
792
True
793
sage: 0 in FrozenBitset([1,2])
794
False
795
sage: 10 in FrozenBitset([0,1])
796
False
797
sage: 121 in FrozenBitset('110' * 50)
798
True
799
sage: 122 in FrozenBitset('110' * 50)
800
False
801
802
TESTS::
803
804
sage: None in FrozenBitset([0,1])
805
Traceback (most recent call last):
806
...
807
TypeError: an integer is required
808
"""
809
if n < self._bitset.size:
810
return bitset_in(self._bitset, n)
811
else:
812
return False
813
814
def __len__(self):
815
"""
816
Return the number of elements in the bitset (which may be
817
different from the capacity of the bitset).
818
819
EXAMPLES::
820
821
sage: len(FrozenBitset([0,1], capacity=10))
822
2
823
sage: len(FrozenBitset(range(98)))
824
98
825
"""
826
return bitset_len(self._bitset)
827
828
def __str__(self):
829
"""
830
Return a string representing the bitset as a binary vector.
831
832
EXAMPLES::
833
834
sage: a = FrozenBitset('10110')
835
sage: str(a)
836
'10110'
837
sage: str(FrozenBitset('110' * 32))
838
'110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110'
839
"""
840
return bitset_string(self._bitset)
841
842
def __repr__(self):
843
"""
844
Return a string representing the bitset as a binary vector.
845
846
EXAMPLES::
847
848
sage: a = FrozenBitset('10110')
849
sage: repr(a)
850
'10110'
851
sage: repr(FrozenBitset('110' * 32))
852
'110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110110'
853
"""
854
return self.__str__()
855
856
cpdef _union(self, FrozenBitset other):
857
"""
858
Return the union of ``self`` and ``other``.
859
860
In order to get a Cython "union" function, we have to use the
861
underscore since "union" is a C keyword.
862
863
EXAMPLES::
864
865
sage: FrozenBitset('10101')._union(FrozenBitset('11100'))
866
11101
867
sage: FrozenBitset('10101' * 10)._union(FrozenBitset('01010' * 10))
868
11111111111111111111111111111111111111111111111111
869
870
TESTS::
871
872
sage: set(FrozenBitset('10101' * 10)._union(FrozenBitset('01010' * 10))) == set(FrozenBitset('10101' * 10)).union(FrozenBitset('01010' * 10))
873
True
874
sage: set(FrozenBitset('10101')._union(FrozenBitset('01010' * 20))) == set(FrozenBitset('10101')).union(FrozenBitset('01010' * 20))
875
True
876
sage: set(FrozenBitset('10101' * 20)._union(FrozenBitset('01010'))) == set(FrozenBitset('10101' * 20)).union(FrozenBitset('01010'))
877
True
878
sage: FrozenBitset('10101' * 10)._union(None)
879
Traceback (most recent call last):
880
...
881
ValueError: other cannot be None
882
"""
883
if other is None:
884
raise ValueError("other cannot be None")
885
cdef FrozenBitset temp, smaller, larger
886
if self._bitset.size <= other._bitset.size:
887
smaller = self
888
larger = other
889
else:
890
smaller = other
891
larger = self
892
893
temp = self._new(smaller._bitset.size)
894
bitset_copy(temp._bitset, smaller._bitset)
895
bitset_realloc(temp._bitset, larger._bitset.size)
896
bitset_union(temp._bitset, temp._bitset, larger._bitset)
897
return temp
898
899
def union(self, FrozenBitset other):
900
"""
901
Return the union of ``self`` and ``other``.
902
903
EXAMPLES::
904
905
sage: FrozenBitset('10101').union(FrozenBitset('11100'))
906
11101
907
sage: FrozenBitset('10101' * 10).union(FrozenBitset('01010' * 10))
908
11111111111111111111111111111111111111111111111111
909
910
TESTS::
911
912
sage: set(FrozenBitset('10101' * 10).union(FrozenBitset('01010' * 10))) == set(FrozenBitset('10101' * 10)).union(FrozenBitset('01010' * 10))
913
True
914
sage: set(FrozenBitset('10101').union(FrozenBitset('01010' * 20))) == set(FrozenBitset('10101')).union(FrozenBitset('01010' * 20))
915
True
916
sage: set(FrozenBitset('10101' * 20).union(FrozenBitset('01010'))) == set(FrozenBitset('10101' * 20)).union(FrozenBitset('01010'))
917
True
918
sage: FrozenBitset('10101' * 10).union(None)
919
Traceback (most recent call last):
920
...
921
ValueError: other cannot be None
922
"""
923
return self._union(other)
924
925
def __or__(self, FrozenBitset other not None):
926
"""
927
Return the union of ``self`` and ``other``.
928
929
EXAMPLES::
930
931
sage: FrozenBitset('10101') | FrozenBitset('11100')
932
11101
933
sage: FrozenBitset('10101' * 10) | FrozenBitset('01010' * 10)
934
11111111111111111111111111111111111111111111111111
935
936
TESTS::
937
938
sage: set(FrozenBitset('10101' * 10) | FrozenBitset('01010' * 10)) == set(FrozenBitset('10101' * 10)) | set(FrozenBitset('01010' * 10))
939
True
940
sage: set(FrozenBitset('10101') | FrozenBitset('01010' * 20)) == set(FrozenBitset('10101')) | set(FrozenBitset('01010' * 20))
941
True
942
sage: set(FrozenBitset('10101' * 20) | FrozenBitset('01010')) == set(FrozenBitset('10101' * 20)) | set(FrozenBitset('01010'))
943
True
944
sage: FrozenBitset('10101') | None
945
Traceback (most recent call last):
946
...
947
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
948
sage: None | FrozenBitset('10101')
949
Traceback (most recent call last):
950
...
951
AttributeError: 'NoneType' object has no attribute '_union'
952
"""
953
return self._union(other)
954
955
cpdef intersection(self, FrozenBitset other):
956
"""
957
Return the intersection of ``self`` and ``other``.
958
959
EXAMPLES::
960
961
sage: FrozenBitset('10101').intersection(FrozenBitset('11100'))
962
10100
963
sage: FrozenBitset('11111' * 10).intersection(FrozenBitset('010101' * 10))
964
010101010101010101010101010101010101010101010101010000000000
965
966
TESTS::
967
968
sage: set(FrozenBitset('11111' * 10).intersection(FrozenBitset('010101' * 10))) == set(FrozenBitset('11111' * 10)).intersection(FrozenBitset('010101' * 10))
969
True
970
sage: set(FrozenBitset('1' * 5).intersection(FrozenBitset('01010' * 20))) == set(FrozenBitset('1' * 5)).intersection(FrozenBitset('01010' * 20))
971
True
972
sage: set(FrozenBitset('10101' * 20).intersection(FrozenBitset('1' * 5))) == set(FrozenBitset('10101' * 20)).intersection(FrozenBitset('1' * 5))
973
True
974
sage: FrozenBitset("101011").intersection(None)
975
Traceback (most recent call last):
976
...
977
ValueError: other cannot be None
978
"""
979
if other is None:
980
raise ValueError("other cannot be None")
981
cdef FrozenBitset temp, smaller, larger
982
if self._bitset.size <= other._bitset.size:
983
smaller = self
984
larger = other
985
else:
986
smaller = other
987
larger = self
988
989
temp = self._new(smaller._bitset.size)
990
bitset_copy(temp._bitset, smaller._bitset)
991
bitset_realloc(temp._bitset, larger._bitset.size)
992
bitset_intersection(temp._bitset, temp._bitset, larger._bitset)
993
return temp
994
995
def __and__(self, FrozenBitset other not None):
996
"""
997
Return the intersection of ``self`` and ``other``.
998
999
EXAMPLES::
1000
1001
sage: FrozenBitset('10101') & FrozenBitset('11100')
1002
10100
1003
sage: FrozenBitset('11111' * 10) & FrozenBitset('010101' * 10)
1004
010101010101010101010101010101010101010101010101010000000000
1005
1006
TESTS::
1007
1008
sage: set(FrozenBitset('11111' * 10) & FrozenBitset('010101' * 10)) == set(FrozenBitset('11111' * 10)) & set(FrozenBitset('010101' * 10))
1009
True
1010
sage: set(FrozenBitset('1' * 5) & FrozenBitset('01010' * 20)) == set(FrozenBitset('1' * 5)) & set(FrozenBitset('01010' * 20))
1011
True
1012
sage: set(FrozenBitset('10101' * 20) & FrozenBitset('1' * 5)) == set(FrozenBitset('10101' * 20)) & set(FrozenBitset('1' * 5))
1013
True
1014
sage: FrozenBitset("101011") & None
1015
Traceback (most recent call last):
1016
...
1017
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1018
sage: None & FrozenBitset("101011")
1019
Traceback (most recent call last):
1020
...
1021
AttributeError: 'NoneType' object has no attribute 'intersection'
1022
"""
1023
return self.intersection(other)
1024
1025
cpdef difference(self, FrozenBitset other):
1026
"""
1027
Return the difference of ``self`` and ``other``.
1028
1029
EXAMPLES::
1030
1031
sage: FrozenBitset('10101').difference(FrozenBitset('11100'))
1032
00001
1033
sage: FrozenBitset('11111' * 10).difference(FrozenBitset('010101' * 10))
1034
101010101010101010101010101010101010101010101010100000000000
1035
1036
TESTS::
1037
1038
sage: set(FrozenBitset('11111' * 10).difference(FrozenBitset('010101' * 10))) == set(FrozenBitset('11111' * 10)).difference(FrozenBitset('010101' * 10))
1039
True
1040
sage: set(FrozenBitset('1' * 5).difference(FrozenBitset('01010' * 20))) == set(FrozenBitset('1' * 5)).difference(FrozenBitset('01010' * 20))
1041
True
1042
sage: set(FrozenBitset('10101' * 20).difference(FrozenBitset('1' * 5))) == set(FrozenBitset('10101' * 20)).difference(FrozenBitset('1' * 5))
1043
True
1044
sage: FrozenBitset('10101').difference(None)
1045
Traceback (most recent call last):
1046
...
1047
ValueError: other cannot be None
1048
"""
1049
if other is None:
1050
raise ValueError("other cannot be None")
1051
cdef FrozenBitset temp = self._new(self._bitset.size)
1052
bitset_copy(temp._bitset, self._bitset)
1053
1054
if temp._bitset.size == other._bitset.size:
1055
bitset_difference(temp._bitset, temp._bitset, other._bitset)
1056
elif temp._bitset.size < other._bitset.size:
1057
bitset_realloc(temp._bitset, other._bitset.size)
1058
bitset_difference(temp._bitset, temp._bitset, other._bitset)
1059
else:
1060
bitset_difference(temp._bitset, temp._bitset, other._larger_capacity_(temp._bitset.size)._bitset)
1061
1062
return temp
1063
1064
def __sub__(self, FrozenBitset other not None):
1065
"""
1066
Return the difference of ``self`` and ``other``.
1067
1068
EXAMPLES::
1069
1070
sage: FrozenBitset('10101') - FrozenBitset('11100')
1071
00001
1072
sage: FrozenBitset('11111' * 10)-FrozenBitset('010101' * 10)
1073
101010101010101010101010101010101010101010101010100000000000
1074
1075
TESTS::
1076
1077
sage: set(FrozenBitset('11111' * 10)-FrozenBitset('010101' * 10)) == set(FrozenBitset('11111' * 10))-set(FrozenBitset('010101' * 10))
1078
True
1079
sage: set(FrozenBitset('1' * 5)-FrozenBitset('01010' * 20)) == set(FrozenBitset('1' * 5))-set(FrozenBitset('01010' * 20))
1080
True
1081
sage: set(FrozenBitset('10101' * 20)-FrozenBitset('1' * 5)) == set(FrozenBitset('10101' * 20))-set(FrozenBitset('1' * 5))
1082
True
1083
sage: FrozenBitset('10101') - None
1084
Traceback (most recent call last):
1085
...
1086
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1087
sage: None - FrozenBitset('10101')
1088
Traceback (most recent call last):
1089
...
1090
AttributeError: 'NoneType' object has no attribute 'difference'
1091
"""
1092
return self.difference(other)
1093
1094
cpdef symmetric_difference(self, FrozenBitset other):
1095
"""
1096
Return the symmetric difference of ``self`` and ``other``.
1097
1098
EXAMPLES::
1099
1100
sage: FrozenBitset('10101').symmetric_difference(FrozenBitset('11100'))
1101
01001
1102
sage: FrozenBitset('11111' * 10).symmetric_difference(FrozenBitset('010101' * 10))
1103
101010101010101010101010101010101010101010101010100101010101
1104
1105
TESTS::
1106
1107
sage: set(FrozenBitset('11111' * 10).symmetric_difference(FrozenBitset('010101' * 10))) == set(FrozenBitset('11111' * 10)).symmetric_difference(FrozenBitset('010101' * 10))
1108
True
1109
sage: set(FrozenBitset('1' * 5).symmetric_difference(FrozenBitset('01010' * 20))) == set(FrozenBitset('1' * 5)).symmetric_difference(FrozenBitset('01010' * 20))
1110
True
1111
sage: set(FrozenBitset('10101' * 20).symmetric_difference(FrozenBitset('1' * 5))) == set(FrozenBitset('10101' * 20)).symmetric_difference(FrozenBitset('1' * 5))
1112
True
1113
sage: FrozenBitset('11111' * 10).symmetric_difference(None)
1114
Traceback (most recent call last):
1115
...
1116
ValueError: other cannot be None
1117
"""
1118
if other is None:
1119
raise ValueError("other cannot be None")
1120
cdef FrozenBitset temp, smaller, larger
1121
if self._bitset.size <= other._bitset.size:
1122
smaller = self
1123
larger = other
1124
else:
1125
smaller = other
1126
larger = self
1127
1128
temp = self._new(smaller._bitset.size)
1129
bitset_copy(temp._bitset, smaller._bitset)
1130
bitset_realloc(temp._bitset, larger._bitset.size)
1131
bitset_symmetric_difference(temp._bitset, temp._bitset, larger._bitset)
1132
return temp
1133
1134
def __xor__(self, FrozenBitset other not None):
1135
"""
1136
Return the symmetric difference of ``self`` and ``other``.
1137
1138
Note that because of the Sage preprocessor, in Sage, ``^^`` is the
1139
exclusive or, rather than ``^``.
1140
1141
EXAMPLES::
1142
1143
sage: FrozenBitset('10101') ^^ FrozenBitset('11100')
1144
01001
1145
sage: FrozenBitset('11111' * 10) ^^ FrozenBitset('010101' * 10)
1146
101010101010101010101010101010101010101010101010100101010101
1147
1148
TESTS::
1149
1150
sage: set(FrozenBitset('11111' * 10) ^^ FrozenBitset('010101' * 10)) == set(FrozenBitset('11111' * 10)) ^^ set(FrozenBitset('010101' * 10))
1151
True
1152
sage: set(FrozenBitset('1' * 5) ^^ FrozenBitset('01010' * 20)) == set(FrozenBitset('1' * 5)) ^^ set(FrozenBitset('01010' * 20))
1153
True
1154
sage: set(FrozenBitset('10101' * 20) ^^ FrozenBitset('1' * 5)) == set(FrozenBitset('10101' * 20)) ^^ set(FrozenBitset('1' * 5))
1155
True
1156
sage: FrozenBitset('11111' * 10) ^^ None
1157
Traceback (most recent call last):
1158
...
1159
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1160
sage: None ^^ FrozenBitset('11111' * 10)
1161
Traceback (most recent call last):
1162
...
1163
AttributeError: 'NoneType' object has no attribute 'symmetric_difference'
1164
"""
1165
return self.symmetric_difference(other)
1166
1167
cpdef complement(self):
1168
"""
1169
Return the complement of self.
1170
1171
EXAMPLES::
1172
1173
sage: ~FrozenBitset('10101')
1174
01010
1175
sage: ~FrozenBitset('11111'*10)
1176
00000000000000000000000000000000000000000000000000
1177
sage: x = FrozenBitset('10'*40)
1178
sage: x == ~x
1179
False
1180
sage: x == ~~x
1181
True
1182
sage: x|(~x) == FrozenBitset('11'*40)
1183
True
1184
sage: ~x == FrozenBitset('01'*40)
1185
True
1186
"""
1187
cdef FrozenBitset temp = self._new(self._bitset.size)
1188
bitset_complement(temp._bitset, self._bitset)
1189
return temp
1190
1191
def __invert__(self):
1192
"""
1193
Return the complement of self.
1194
1195
EXAMPLES::
1196
1197
sage: ~FrozenBitset('10101')
1198
01010
1199
sage: ~FrozenBitset('11111'*10)
1200
00000000000000000000000000000000000000000000000000
1201
sage: x = FrozenBitset('10'*40)
1202
sage: x == ~x
1203
False
1204
sage: x == ~~x
1205
True
1206
sage: x|(~x) == FrozenBitset('11'*40)
1207
True
1208
sage: ~x == FrozenBitset('01'*40)
1209
True
1210
"""
1211
return self.complement()
1212
1213
cpdef __copy__(self):
1214
"""
1215
Return ``self`` (since ``self`` is immutable).
1216
1217
EXAMPLES::
1218
1219
sage: a = FrozenBitset('10101')
1220
sage: from copy import copy
1221
sage: b = copy(a)
1222
sage: b is a
1223
True
1224
sage: c = FrozenBitset('1010' * 32)
1225
sage: d = copy(c)
1226
sage: d is c
1227
True
1228
"""
1229
return self
1230
1231
cdef class Bitset(FrozenBitset):
1232
r"""
1233
A bitset class which leverages inline Cython functions for creating
1234
and manipulating bitsets. See the class documentation of
1235
:class:`FrozenBitset` for details on the parameters of the constructor
1236
and how to interpret the string representation of a :class:`Bitset`.
1237
1238
A bitset can be thought of in two ways. First, as a set of elements
1239
from the universe of the `n` natural numbers `0, 1, \dots, n-1` (where
1240
the capacity `n` can be specified), with typical set operations such as
1241
intersection, union, symmetric difference, etc. Secondly, a bitset can
1242
be thought of as a binary vector with typical binary operations such as
1243
``and``, ``or``, ``xor``, etc. This class supports both interfaces.
1244
1245
The interface in this class mirrors the interface in the ``set``
1246
data type of Python.
1247
1248
.. warning::
1249
1250
This class is most likely to be useful as a way to store
1251
Cython bitsets in Python data structures, acting on them using
1252
the Cython inline functions. If you want to use this class
1253
for a Python set type, the Python ``set`` data type may be
1254
faster.
1255
1256
.. seealso::
1257
1258
- :class:`FrozenBitset`
1259
- Python's `set types <http://docs.python.org/library/stdtypes.html#set-types-set-frozenset>`_
1260
1261
EXAMPLES::
1262
1263
sage: a = Bitset('1101')
1264
sage: loads(dumps(a)) == a
1265
True
1266
sage: a = Bitset('1101' * 32)
1267
sage: loads(dumps(a)) == a
1268
True
1269
"""
1270
1271
cpdef __copy__(self):
1272
"""
1273
Return a copy of ``self``.
1274
1275
EXAMPLES::
1276
1277
sage: a = Bitset('10101')
1278
sage: from copy import copy
1279
sage: b = copy(a)
1280
sage: b is a
1281
False
1282
sage: b == a
1283
True
1284
sage: c = Bitset('1010' * 32)
1285
sage: d = copy(c)
1286
sage: d is c
1287
False
1288
sage: d == c
1289
True
1290
"""
1291
cdef FrozenBitset temp = self._new(self._bitset.size)
1292
bitset_copy(temp._bitset, self._bitset)
1293
return temp
1294
1295
def __hash__(self):
1296
"""
1297
Raise an error, since mutable ``Bitset``s are not hashable.
1298
1299
EXAMPLE::
1300
1301
sage: hash(Bitset('110'))
1302
Traceback (most recent call last):
1303
...
1304
TypeError: Bitset objects are unhashable; use FrozenBitset
1305
"""
1306
raise TypeError("Bitset objects are unhashable; use FrozenBitset")
1307
1308
def __richcmp__(FrozenBitset self, FrozenBitset other not None, int op):
1309
"""
1310
Implement comparisons, using the Cython richcmp convention.
1311
Comparison is done by inclusion. That is, a set ``A`` is less than
1312
another set ``B``, written ``A < B``, if ``A`` is a subset of ``B``.
1313
1314
EXAMPLES::
1315
1316
sage: Bitset('11') < Bitset('101')
1317
False
1318
sage: Bitset('11') <= Bitset('110')
1319
True
1320
sage: Bitset('11') != Bitset('10')
1321
True
1322
sage: Bitset('11') == Bitset('10')
1323
False
1324
sage: Bitset('11') == Bitset('110')
1325
True
1326
sage: Bitset('11') > Bitset('10')
1327
True
1328
sage: Bitset('11') >= Bitset('10')
1329
True
1330
sage: FrozenBitset('11') < FrozenBitset('110' * 32)
1331
True
1332
1333
TESTS:
1334
1335
During comparison, ``other`` cannot be ``None``. ::
1336
1337
sage: Bitset('11') < None
1338
Traceback (most recent call last):
1339
...
1340
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1341
sage: Bitset('11') <= None
1342
Traceback (most recent call last):
1343
...
1344
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1345
sage: Bitset('11') > None
1346
Traceback (most recent call last):
1347
...
1348
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1349
sage: Bitset('11') >= None
1350
Traceback (most recent call last):
1351
...
1352
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1353
sage: Bitset('11') == None
1354
Traceback (most recent call last):
1355
...
1356
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1357
sage: Bitset('11') != None
1358
Traceback (most recent call last):
1359
...
1360
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1361
sage: None < Bitset('11')
1362
Traceback (most recent call last):
1363
...
1364
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1365
sage: None <= Bitset('11')
1366
Traceback (most recent call last):
1367
...
1368
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1369
sage: None > Bitset('11')
1370
Traceback (most recent call last):
1371
...
1372
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1373
sage: None >= Bitset('11')
1374
Traceback (most recent call last):
1375
...
1376
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1377
sage: None == Bitset('11')
1378
Traceback (most recent call last):
1379
...
1380
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1381
sage: None != Bitset('11')
1382
Traceback (most recent call last):
1383
...
1384
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1385
"""
1386
cdef FrozenBitset left, right
1387
1388
if self._bitset.size == other._bitset.size:
1389
left = self
1390
right = other
1391
elif self._bitset.size < other._bitset.size:
1392
left = self._larger_capacity_(other._bitset.size)
1393
right = other
1394
else:
1395
left = self
1396
right = other._larger_capacity_(self._bitset.size)
1397
1398
if op == 2: # ==
1399
return bitset_eq(left._bitset, right._bitset)
1400
elif op == 3: # !=
1401
return not bitset_eq(left._bitset, right._bitset)
1402
elif op == 0: # <
1403
return bitset_issubset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
1404
elif op == 1: # <=
1405
return bitset_issubset(left._bitset, right._bitset)
1406
elif op == 4: # >
1407
return bitset_issuperset(left._bitset, right._bitset) and not bitset_eq(left._bitset, right._bitset)
1408
elif op == 5: # >=
1409
return bitset_issuperset(left._bitset, right._bitset)
1410
1411
cdef FrozenBitset _new(self, long int capacity):
1412
"""
1413
Return an object of the same type as ``self``, initialized with a
1414
bitset of capacity ``capacity``.
1415
"""
1416
cdef Bitset b
1417
b = Bitset.__new__(Bitset, None, capacity)
1418
return b
1419
1420
cpdef update(self, FrozenBitset other):
1421
"""
1422
Update the bitset to include items in ``other``.
1423
1424
EXAMPLES::
1425
1426
sage: a = Bitset('110')
1427
sage: a.update(Bitset('0101'))
1428
sage: a
1429
1101
1430
sage: a_set = set(a)
1431
sage: a.update(Bitset('00011' * 25))
1432
sage: a
1433
11011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011
1434
sage: a_set.update(Bitset('00011' * 25))
1435
sage: set(a) == a_set
1436
True
1437
1438
TESTS:
1439
1440
During update, ``other`` cannot be ``None``. ::
1441
1442
sage: a = Bitset('1101')
1443
sage: a.update(None)
1444
Traceback (most recent call last):
1445
...
1446
TypeError: other cannot be None
1447
"""
1448
if other is None:
1449
raise TypeError("other cannot be None")
1450
cdef bitset_t temp
1451
if self._bitset.size == other._bitset.size:
1452
bitset_union(self._bitset, self._bitset, other._bitset)
1453
elif self._bitset.size < other._bitset.size:
1454
bitset_realloc(self._bitset, other._bitset.size)
1455
bitset_union(self._bitset, self._bitset, other._bitset)
1456
else:
1457
bitset_init(temp, other._bitset.size)
1458
bitset_copy(temp, other._bitset)
1459
bitset_realloc(temp, self._bitset.size)
1460
bitset_union(self._bitset, self._bitset, temp)
1461
bitset_free(temp)
1462
1463
def __ior__(self, FrozenBitset other not None):
1464
"""
1465
Update the bitset to include items in ``other``.
1466
1467
EXAMPLES::
1468
1469
sage: a = Bitset('110')
1470
sage: a |= Bitset('0101')
1471
sage: a
1472
1101
1473
sage: a_set = set(a)
1474
sage: a |= Bitset('00011' * 25)
1475
sage: a
1476
11011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011000110001100011
1477
sage: a_set |= set(Bitset('00011' * 25))
1478
sage: set(a) == a_set
1479
True
1480
1481
TESTS::
1482
1483
sage: a = Bitset('110')
1484
sage: a |= None
1485
Traceback (most recent call last):
1486
...
1487
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1488
"""
1489
self.update(other)
1490
return self
1491
1492
cpdef intersection_update(self, FrozenBitset other):
1493
"""
1494
Update the bitset to the intersection of ``self`` and ``other``.
1495
1496
EXAMPLES::
1497
1498
sage: a = Bitset('110')
1499
sage: a.intersection_update(Bitset('0101'))
1500
sage: a
1501
0100
1502
sage: a_set = set(a)
1503
sage: a.intersection_update(Bitset('0110' * 25))
1504
sage: a
1505
0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1506
sage: a_set.intersection_update(Bitset('0110' * 25))
1507
sage: set(a) == a_set
1508
True
1509
1510
TESTS::
1511
1512
sage: Bitset('110').intersection_update(None)
1513
Traceback (most recent call last):
1514
...
1515
TypeError: other cannot be None
1516
"""
1517
if other is None:
1518
raise TypeError("other cannot be None")
1519
cdef bitset_t temp
1520
if self._bitset.size == other._bitset.size:
1521
bitset_intersection(self._bitset, self._bitset, other._bitset)
1522
elif self._bitset.size < other._bitset.size:
1523
bitset_realloc(self._bitset, other._bitset.size)
1524
bitset_intersection(self._bitset, self._bitset, other._bitset)
1525
else:
1526
bitset_init(temp, other._bitset.size)
1527
bitset_copy(temp, other._bitset)
1528
bitset_realloc(temp, self._bitset.size)
1529
bitset_intersection(self._bitset, self._bitset, temp)
1530
bitset_free(temp)
1531
1532
def __iand__(self, FrozenBitset other not None):
1533
"""
1534
Update the bitset to the intersection of ``self`` and ``other``.
1535
1536
EXAMPLES::
1537
1538
sage: a = Bitset('110')
1539
sage: a &= Bitset('0101')
1540
sage: a
1541
0100
1542
sage: a_set = set(a)
1543
sage: a &= Bitset('0110' * 25)
1544
sage: a
1545
0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1546
sage: a_set &= set(Bitset('0110' * 25))
1547
sage: a_set == set(a)
1548
True
1549
1550
TESTS::
1551
1552
sage: a = Bitset('110')
1553
sage: a &= None
1554
Traceback (most recent call last):
1555
...
1556
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1557
"""
1558
self.intersection_update(other)
1559
return self
1560
1561
cpdef difference_update(self, FrozenBitset other):
1562
"""
1563
Update the bitset to the difference of ``self`` and ``other``.
1564
1565
EXAMPLES::
1566
1567
sage: a = Bitset('110')
1568
sage: a.difference_update(Bitset('0101'))
1569
sage: a
1570
1000
1571
sage: a_set = set(a)
1572
sage: a.difference_update(FrozenBitset('010101' * 10)); a
1573
100000000000000000000000000000000000000000000000000000000000
1574
sage: a_set.difference_update(FrozenBitset('010101' * 10))
1575
sage: a_set == set(a)
1576
True
1577
sage: a.difference_update(FrozenBitset('110'))
1578
sage: a_set.difference_update(FrozenBitset('110'))
1579
sage: a_set == set(a)
1580
True
1581
sage: a.difference_update(FrozenBitset('01010' * 20)); a
1582
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1583
sage: a_set.difference_update(FrozenBitset('01010' * 20))
1584
sage: a_set == set(a)
1585
True
1586
sage: b = Bitset('10101' * 20)
1587
sage: b_set = set(b)
1588
sage: b.difference_update(FrozenBitset('1' * 5)); b
1589
0000010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1590
sage: b_set.difference_update(FrozenBitset('1' * 5))
1591
sage: b_set == set(b)
1592
True
1593
1594
TESTS::
1595
1596
sage: Bitset('110').difference_update(None)
1597
Traceback (most recent call last):
1598
...
1599
TypeError: other cannot be None
1600
"""
1601
if other is None:
1602
raise TypeError("other cannot be None")
1603
cdef bitset_t temp
1604
if self._bitset.size == other._bitset.size:
1605
bitset_difference(self._bitset, self._bitset, other._bitset)
1606
elif self._bitset.size < other._bitset.size:
1607
bitset_realloc(self._bitset, other._bitset.size)
1608
bitset_difference(self._bitset, self._bitset, other._bitset)
1609
else:
1610
bitset_init(temp, other._bitset.size)
1611
bitset_copy(temp, other._bitset)
1612
bitset_realloc(temp, self._bitset.size)
1613
bitset_difference(self._bitset, self._bitset, temp)
1614
bitset_free(temp)
1615
1616
def __isub__(self, FrozenBitset other not None):
1617
"""
1618
Update the bitset to the difference of ``self`` and ``other``.
1619
1620
EXAMPLES::
1621
1622
sage: a = Bitset('110')
1623
sage: a -= Bitset('0101')
1624
sage: a
1625
1000
1626
sage: a_set = set(a)
1627
sage: a -= FrozenBitset('010101' * 10); a
1628
100000000000000000000000000000000000000000000000000000000000
1629
sage: a_set -= set(FrozenBitset('010101' * 10))
1630
sage: a_set == set(a)
1631
True
1632
sage: a = Bitset('110')
1633
sage: a_set = set(a)
1634
sage: a -= FrozenBitset('01010' * 20); a
1635
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1636
sage: a_set -= set(FrozenBitset('01010' * 20))
1637
sage: a_set == set(a)
1638
True
1639
sage: b = FrozenBitset('10101' * 20)
1640
sage: b_set = set(b)
1641
sage: b -= FrozenBitset('1' * 5); b
1642
0000010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1643
sage: b_set -= FrozenBitset('1' * 5)
1644
sage: b_set == set(b)
1645
True
1646
1647
TESTS::
1648
1649
sage: a = Bitset('110')
1650
sage: a -= None
1651
Traceback (most recent call last):
1652
...
1653
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1654
"""
1655
self.difference_update(other)
1656
return self
1657
1658
cpdef symmetric_difference_update(self, FrozenBitset other):
1659
"""
1660
Update the bitset to the symmetric difference of ``self`` and
1661
``other``.
1662
1663
EXAMPLES::
1664
1665
sage: a = Bitset('110')
1666
sage: a.symmetric_difference_update(Bitset('0101'))
1667
sage: a
1668
1001
1669
sage: a_set = set(a)
1670
sage: a.symmetric_difference_update(FrozenBitset('010101' * 10)); a
1671
110001010101010101010101010101010101010101010101010101010101
1672
sage: a_set.symmetric_difference_update(FrozenBitset('010101' * 10))
1673
sage: a_set == set(a)
1674
True
1675
sage: a.symmetric_difference_update(FrozenBitset('01010' * 20)); a
1676
1001011111000001111100000111110000011111000001111100000111110101001010010100101001010010100101001010
1677
sage: a_set.symmetric_difference_update(FrozenBitset('01010' * 20))
1678
sage: a_set == set(a)
1679
True
1680
sage: b = Bitset('10101' * 20)
1681
sage: b_set = set(b)
1682
sage: b.symmetric_difference_update( FrozenBitset('1' * 5)); b
1683
0101010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1684
sage: b_set.symmetric_difference_update( FrozenBitset('1' * 5))
1685
sage: b_set == set(b)
1686
True
1687
1688
TESTS::
1689
1690
sage: Bitset('110').symmetric_difference_update(None)
1691
Traceback (most recent call last):
1692
...
1693
TypeError: other cannot be None
1694
"""
1695
if other is None:
1696
raise TypeError("other cannot be None")
1697
cdef bitset_t temp
1698
if self._bitset.size == other._bitset.size:
1699
bitset_symmetric_difference(self._bitset, self._bitset, other._bitset)
1700
elif self._bitset.size < other._bitset.size:
1701
bitset_realloc(self._bitset, other._bitset.size)
1702
bitset_symmetric_difference(self._bitset, self._bitset, other._bitset)
1703
else:
1704
bitset_init(temp, other._bitset.size)
1705
bitset_copy(temp, other._bitset)
1706
bitset_realloc(temp, self._bitset.size)
1707
bitset_symmetric_difference(self._bitset, self._bitset, temp)
1708
bitset_free(temp)
1709
1710
def __ixor__(self, FrozenBitset other not None):
1711
"""
1712
Update the bitset to the symmetric difference of ``self`` and
1713
``other``.
1714
1715
EXAMPLES::
1716
1717
sage: a = Bitset('110')
1718
sage: a ^^=Bitset('0101')
1719
sage: a
1720
1001
1721
sage: a_set = set(a)
1722
sage: a ^^= FrozenBitset('010101' * 10); a
1723
110001010101010101010101010101010101010101010101010101010101
1724
sage: a_set ^^= set(FrozenBitset('010101' * 10))
1725
sage: a_set == set(a)
1726
True
1727
sage: a ^^= FrozenBitset('01010' * 20); a
1728
1001011111000001111100000111110000011111000001111100000111110101001010010100101001010010100101001010
1729
sage: a_set ^^= set(FrozenBitset('01010' * 20))
1730
sage: a_set == set(a)
1731
True
1732
sage: b = Bitset('10101' * 20)
1733
sage: b_set = set(b)
1734
sage: b ^^= FrozenBitset('1' * 5); b
1735
0101010101101011010110101101011010110101101011010110101101011010110101101011010110101101011010110101
1736
sage: b_set ^^= set(FrozenBitset('1' * 5))
1737
sage: b_set == set(b)
1738
True
1739
1740
TESTS::
1741
1742
sage: a = Bitset('110')
1743
sage: a ^^= None
1744
Traceback (most recent call last):
1745
...
1746
TypeError: Argument 'other' has incorrect type (expected sage.misc.bitset.FrozenBitset, got NoneType)
1747
"""
1748
self.symmetric_difference_update(other)
1749
return self
1750
1751
cpdef add(self, unsigned long n):
1752
"""
1753
Update the bitset by adding ``n``.
1754
1755
EXAMPLES::
1756
1757
sage: a = Bitset('110')
1758
sage: a.add(5)
1759
sage: a
1760
110001
1761
sage: a.add(100)
1762
sage: sorted(list(a))
1763
[0, 1, 5, 100]
1764
sage: a.capacity()
1765
101
1766
1767
TESTS:
1768
1769
The input ``n`` must be an integer. ::
1770
1771
sage: Bitset('110').add(None)
1772
Traceback (most recent call last):
1773
...
1774
TypeError: an integer is required
1775
"""
1776
if n >= self._bitset.size:
1777
bitset_realloc(self._bitset, n + 1)
1778
bitset_add(self._bitset, n)
1779
1780
cpdef remove(self, unsigned long n):
1781
"""
1782
Update the bitset by removing ``n``. Raises ``KeyError`` if ``n`` is
1783
not contained in the bitset.
1784
1785
EXAMPLES::
1786
1787
sage: a = Bitset('110')
1788
sage: a.remove(1)
1789
sage: a
1790
100
1791
sage: a.remove(2)
1792
Traceback (most recent call last):
1793
...
1794
KeyError: 2L
1795
sage: a.remove(4)
1796
Traceback (most recent call last):
1797
...
1798
KeyError: 4L
1799
sage: a
1800
100
1801
sage: a = Bitset('000001' * 15); sorted(list(a))
1802
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89]
1803
sage: a.remove(83); sorted(list(a))
1804
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 89]
1805
1806
TESTS:
1807
1808
The input ``n`` must be an integer. ::
1809
1810
sage: Bitset('110').remove(None)
1811
Traceback (most recent call last):
1812
...
1813
TypeError: an integer is required
1814
"""
1815
if n >= self._bitset.size:
1816
raise KeyError(n)
1817
else:
1818
bitset_remove(self._bitset, n)
1819
1820
cpdef discard(self, unsigned long n):
1821
"""
1822
Update the bitset by removing ``n``.
1823
1824
EXAMPLES::
1825
1826
sage: a = Bitset('110')
1827
sage: a.discard(1)
1828
sage: a
1829
100
1830
sage: a.discard(2)
1831
sage: a.discard(4)
1832
sage: a
1833
100
1834
sage: a = Bitset('000001' * 15); sorted(list(a))
1835
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89]
1836
sage: a.discard(83); sorted(list(a))
1837
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 89]
1838
sage: a.discard(82); sorted(list(a))
1839
[5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 89]
1840
1841
TESTS:
1842
1843
The input ``n`` must be an integer. ::
1844
1845
sage: Bitset('110').discard(None)
1846
Traceback (most recent call last):
1847
...
1848
TypeError: an integer is required
1849
"""
1850
if n < self._bitset.size:
1851
bitset_discard(self._bitset, n)
1852
1853
cpdef pop(self):
1854
"""
1855
Remove and return an arbitrary element from the set. Raises
1856
``KeyError`` if the set is empty.
1857
1858
EXAMPLES::
1859
1860
sage: a = Bitset('011')
1861
sage: a.pop()
1862
1
1863
sage: a
1864
001
1865
sage: a.pop()
1866
2
1867
sage: a
1868
000
1869
sage: a.pop()
1870
Traceback (most recent call last):
1871
...
1872
KeyError: 'pop from an empty set'
1873
sage: a = Bitset('0001'*32)
1874
sage: a.pop()
1875
3
1876
sage: [a.pop() for _ in range(20)]
1877
[7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71, 75, 79, 83]
1878
"""
1879
return bitset_pop(self._bitset)
1880
1881
cpdef clear(self):
1882
"""
1883
Removes all elements from the bitset.
1884
1885
EXAMPLES::
1886
1887
sage: a = Bitset('011')
1888
sage: a.clear()
1889
sage: a
1890
000
1891
sage: a = Bitset('011' * 32)
1892
sage: a.clear()
1893
sage: set(a)
1894
set([])
1895
"""
1896
bitset_clear(self._bitset)
1897
1898
1899
#############################################################################
1900
# Bitset Testing: test basic Cython bitsets
1901
#############################################################################
1902
1903
def test_bitset(py_a, py_b, long n):
1904
"""
1905
Test the Cython bitset functions so we can have some relevant doctests.
1906
1907
TESTS::
1908
1909
sage: from sage.misc.bitset import test_bitset
1910
sage: test_bitset('00101', '01110', 4)
1911
a 00101
1912
list a [2, 4]
1913
a.size 5
1914
len(a) 2
1915
a.limbs 1
1916
b 01110
1917
a.in(n) True
1918
a.not_in(n) False
1919
a.add(n) 00101
1920
a.discard(n) 00100
1921
a.set_to(n) 00101
1922
a.flip(n) 00100
1923
a.set_first_n(n) 11110
1924
a.first_in_complement() 4
1925
a.isempty() False
1926
a.eq(b) False
1927
a.cmp(b) 1
1928
a.lex_cmp(b) -1
1929
a.issubset(b) False
1930
a.issuperset(b) False
1931
a.copy() 00101
1932
r.clear() 00000
1933
complement a 11010
1934
a intersect b 00100
1935
a union b 01111
1936
a minus b 00001
1937
a symmetric_difference b 01011
1938
a.rshift(n) 10000
1939
a.lshift(n) 00000
1940
a.first() 2
1941
a.next(n) 4
1942
a.first_diff(b) 1
1943
a.next_diff(b, n) 4
1944
a.hamming_weight() 2
1945
a.map(m) 10100
1946
a == loads(dumps(a)) True
1947
reallocating a 00101
1948
to size 4 0010
1949
to size 8 00100000
1950
to original size 00100
1951
1952
::
1953
1954
sage: test_bitset('11101', '11001', 2)
1955
a 11101
1956
list a [0, 1, 2, 4]
1957
a.size 5
1958
len(a) 4
1959
a.limbs 1
1960
b 11001
1961
a.in(n) True
1962
a.not_in(n) False
1963
a.add(n) 11101
1964
a.discard(n) 11001
1965
a.set_to(n) 11101
1966
a.flip(n) 11001
1967
a.set_first_n(n) 11000
1968
a.first_in_complement() 2
1969
a.isempty() False
1970
a.eq(b) False
1971
a.cmp(b) 1
1972
a.lex_cmp(b) 1
1973
a.issubset(b) False
1974
a.issuperset(b) True
1975
a.copy() 11101
1976
r.clear() 00000
1977
complement a 00010
1978
a intersect b 11001
1979
a union b 11101
1980
a minus b 00100
1981
a symmetric_difference b 00100
1982
a.rshift(n) 10100
1983
a.lshift(n) 00111
1984
a.first() 0
1985
a.next(n) 2
1986
a.first_diff(b) 2
1987
a.next_diff(b, n) 2
1988
a.hamming_weight() 4
1989
a.map(m) 10111
1990
a == loads(dumps(a)) True
1991
reallocating a 11101
1992
to size 2 11
1993
to size 4 1100
1994
to original size 11000
1995
1996
Test a corner-case: a bitset that is a multiple of words::
1997
1998
sage: test_bitset('00'*64, '01'*64, 127)
1999
a 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2000
list a []
2001
a.size 128
2002
len(a) 0
2003
a.limbs ...
2004
b 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
2005
a.in(n) False
2006
a.not_in(n) True
2007
a.add(n) 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
2008
a.discard(n) 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2009
a.set_to(n) 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
2010
a.flip(n) 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
2011
a.set_first_n(n) 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110
2012
a.first_in_complement() 127
2013
a.isempty() True
2014
a.eq(b) False
2015
a.cmp(b) -1
2016
a.lex_cmp(b) -1
2017
a.issubset(b) True
2018
a.issuperset(b) False
2019
a.copy() 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2020
r.clear() 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2021
complement a 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
2022
a intersect b 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2023
a union b 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
2024
a minus b 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2025
a symmetric_difference b 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
2026
a.rshift(n) 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2027
a.lshift(n) 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2028
a.first() -1
2029
a.next(n) -1
2030
a.first_diff(b) 1
2031
a.next_diff(b, n) 127
2032
a.hamming_weight() 0
2033
a.map(m) 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2034
a == loads(dumps(a)) True
2035
rshifts add True
2036
lshifts add True
2037
intersection commutes True
2038
union commutes True
2039
not not = id True
2040
flipped bit 127
2041
add bit 127
2042
discard bit 127
2043
lshift add unset ok True
2044
rshift set unset ok True
2045
reallocating a 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2046
to size 127 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2047
to size 254 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2048
to original size 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2049
2050
Large enough to span multiple limbs. We don't explicitly check the number of limbs below because it will be different in the 32 bit versus 64 bit cases::
2051
2052
sage: test_bitset('111001'*25, RealField(151)(pi).str(2)[2:], 69)
2053
a 111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001
2054
list a [0, 1, 2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20, 23, 24, 25, 26, 29, 30, 31, 32, 35, 36, 37, 38, 41, 42, 43, 44, 47, 48, 49, 50, 53, 54, 55, 56, 59, 60, 61, 62, 65, 66, 67, 68, 71, 72, 73, 74, 77, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 107, 108, 109, 110, 113, 114, 115, 116, 119, 120, 121, 122, 125, 126, 127, 128, 131, 132, 133, 134, 137, 138, 139, 140, 143, 144, 145, 146, 149]
2055
a.size 150
2056
len(a) 100
2057
a.limbs ...
2058
b 000100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111
2059
a.in(n) False
2060
a.not_in(n) True
2061
a.add(n) 111001111001111001111001111001111001111001111001111001111001111001111101111001111001111001111001111001111001111001111001111001111001111001111001111001
2062
a.discard(n) 111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001
2063
a.set_to(n) 111001111001111001111001111001111001111001111001111001111001111001111101111001111001111001111001111001111001111001111001111001111001111001111001111001
2064
a.flip(n) 111001111001111001111001111001111001111001111001111001111001111001111101111001111001111001111001111001111001111001111001111001111001111001111001111001
2065
a.set_first_n(n) 111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000
2066
a.first_in_complement() 69
2067
a.isempty() False
2068
a.eq(b) False
2069
a.cmp(b) -1
2070
a.lex_cmp(b) 1
2071
a.issubset(b) False
2072
a.issuperset(b) False
2073
a.copy() 111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001
2074
r.clear() 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2075
complement a 000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110000110
2076
a intersect b 000000100001111000110001010001000000001001010001100001000000100000001001100001001000010000010001000000011001100000111001101000100001001000000000100001
2077
a union b 111101111001111111111101111001111101111011111001111001111111111111111001111011111101111101111111111001111011111001111001111001111101111001111101111111
2078
a minus b 111001011000000001001000101000111001110000101000011000111001011001110000011000110001101001101000111001100000011001000000010001011000110001111001011000
2079
a symmetric_difference b 111101011000000111001100101000111101110010101000011000111111011111110000011010110101101101101110111001100010011001000000010001011100110001111101011110
2080
a.rshift(n) 001111001111001111001111001111001111001111001111001111001111001111001111001111001000000000000000000000000000000000000000000000000000000000000000000000
2081
a.lshift(n) 000000000000000000000000000000000000000000000000000000000000000000000111001111001111001111001111001111001111001111001111001111001111001111001111001111
2082
a.first() 0
2083
a.next(n) 71
2084
a.first_diff(b) 0
2085
a.next_diff(b, n) 73
2086
a.hamming_weight() 100
2087
a.map(m) 100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111100111
2088
a == loads(dumps(a)) True
2089
rshifts add True
2090
lshifts add True
2091
intersection commutes True
2092
union commutes True
2093
not not = id True
2094
flipped bit 69
2095
add bit 69
2096
discard bit 69
2097
lshift add unset ok True
2098
rshift set unset ok True
2099
reallocating a 111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001
2100
to size 69 111001111001111001111001111001111001111001111001111001111001111001111
2101
to size 138 111001111001111001111001111001111001111001111001111001111001111001111000000000000000000000000000000000000000000000000000000000000000000000
2102
to original size 111001111001111001111001111001111001111001111001111001111001111001111000000000000000000000000000000000000000000000000000000000000000000000000000000000
2103
2104
"""
2105
cdef bint bit = True
2106
cdef bitset_t a, b, r
2107
2108
bitset_from_str(a, py_a)
2109
bitset_from_str(b, py_b)
2110
2111
if a.size != b.size:
2112
raise ValueError("inputs must have same size")
2113
2114
print "a", bitset_string(a)
2115
print "list a", bitset_list(a)
2116
print "a.size", a.size
2117
print "len(a)", bitset_len(a)
2118
print "a.limbs", a.limbs
2119
print "b", bitset_string(b)
2120
print "a.in(n) ", bitset_in(a, n)
2121
print "a.not_in(n) ", bitset_not_in(a, n)
2122
bitset_add(a, n)
2123
print "a.add(n) ", bitset_string(a)
2124
bitset_from_str(a, py_a)
2125
bitset_discard(a, n)
2126
print "a.discard(n) ", bitset_string(a)
2127
bitset_from_str(a, py_a)
2128
bitset_set_to(a, n, bit)
2129
print "a.set_to(n) ", bitset_string(a)
2130
bitset_from_str(a, py_a)
2131
bitset_flip(a, n)
2132
print "a.flip(n) ", bitset_string(a)
2133
bitset_set_first_n(a, n)
2134
print "a.set_first_n(n) ", bitset_string(a)
2135
print "a.first_in_complement() ", bitset_first_in_complement(a)
2136
2137
bitset_from_str(a, py_a)
2138
bitset_from_str(b, py_b)
2139
print "a.isempty() ", bitset_isempty(a)
2140
print "a.eq(b) ", bitset_eq(a, b)
2141
print "a.cmp(b) ", bitset_cmp(a, b)
2142
print "a.lex_cmp(b)", bitset_lex_cmp(a, b)
2143
print "a.issubset(b)", bitset_issubset(a, b)
2144
print "a.issuperset(b)", bitset_issuperset(a, b)
2145
2146
bitset_from_str(a, py_a)
2147
bitset_from_str(b, py_b)
2148
2149
bitset_init(r, a.size)
2150
bitset_copy(r, a)
2151
print "a.copy() ", bitset_string(r)
2152
bitset_clear(r)
2153
print "r.clear() ", bitset_string(r)
2154
bitset_complement(r, a)
2155
print "complement a ", bitset_string(r)
2156
bitset_intersection(r, a, b)
2157
print "a intersect b ", bitset_string(r)
2158
bitset_union(r, a, b)
2159
print "a union b ", bitset_string(r)
2160
bitset_difference(r, a, b)
2161
print "a minus b ", bitset_string(r)
2162
bitset_symmetric_difference(r, a, b)
2163
print "a symmetric_difference b ", bitset_string(r)
2164
2165
bitset_rshift(r, a, n)
2166
print "a.rshift(n) ", bitset_string(r)
2167
2168
bitset_lshift(r, a, n)
2169
print "a.lshift(n) ", bitset_string(r)
2170
2171
print "a.first() ", bitset_first(a)
2172
print "a.next(n) ", bitset_next(a, n)
2173
print "a.first_diff(b) ", bitset_first_diff(a, b)
2174
print "a.next_diff(b, n) ", bitset_next_diff(a, b, n)
2175
2176
print "a.hamming_weight() ", bitset_hamming_weight(a)
2177
2178
morphism = {}
2179
for i in xrange(a.size):
2180
morphism[i] = a.size - i - 1
2181
bitset_map(r, a, morphism)
2182
print "a.map(m) ", bitset_string(r)
2183
2184
data = bitset_pickle(a)
2185
bitset_unpickle(r, data)
2186
print "a == loads(dumps(a)) ", bitset_eq(r, a)
2187
2188
cdef bitset_t s
2189
bitset_init(s, a.size)
2190
2191
if a.size > 100:
2192
bitset_rshift(r, b, 3)
2193
bitset_rshift(r, r, 77)
2194
bitset_rshift(s, b, 80)
2195
print "rshifts add ", bitset_eq(s, r)
2196
2197
bitset_lshift(r, b, 69)
2198
bitset_lshift(r, r, 6)
2199
bitset_lshift(s, b, 75)
2200
print "lshifts add ", bitset_eq(s, r)
2201
2202
bitset_intersection(r, a, b)
2203
bitset_intersection(s, b, a)
2204
print "intersection commutes", bitset_eq(s, r)
2205
2206
bitset_union(r, a, b)
2207
bitset_union(s, b, a)
2208
print "union commutes ", bitset_eq(s, r)
2209
2210
bitset_complement(r, b)
2211
bitset_complement(s, r)
2212
print "not not = id", bitset_eq(s, b)
2213
2214
bitset_copy(r, b)
2215
bitset_flip(r, n)
2216
print "flipped bit ", bitset_first_diff(b, r)
2217
2218
bitset_clear(r)
2219
bitset_add(r, n)
2220
print "add bit ", bitset_first(r)
2221
2222
bitset_clear(r)
2223
bitset_complement(r, r)
2224
bitset_discard(r, n)
2225
bitset_complement(r, r)
2226
print "discard bit ", bitset_first(r)
2227
2228
bitset_clear(r)
2229
bitset_add(r, 10)
2230
bitset_lshift(r, r, 68)
2231
bitset_flip(r, 78)
2232
print "lshift add unset ok", bitset_isempty(r)
2233
2234
bitset_clear(r)
2235
bitset_add(r, 19)
2236
bitset_rshift(r, r, 8)
2237
bitset_discard(r, 11)
2238
print "rshift set unset ok", bitset_isempty(r)
2239
2240
print "reallocating a ", bitset_string(a)
2241
bitset_realloc(a, n)
2242
print "to size %d " % n, bitset_string(a)
2243
bitset_realloc(a, 2 * n)
2244
print "to size %d " % (2 * n), bitset_string(a)
2245
bitset_realloc(a, b.size)
2246
print "to original size ", bitset_string(a)
2247
2248
bitset_free(a)
2249
bitset_free(b)
2250
bitset_free(r)
2251
bitset_free(s)
2252
2253
2254
def test_bitset_set_first_n(py_a, long n):
2255
"""
2256
Test the bitset function set_first_n.
2257
2258
TESTS::
2259
2260
sage: from sage.misc.bitset import test_bitset_set_first_n
2261
sage: test_bitset_set_first_n('00'*64, 128)
2262
a.set_first_n(n) 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
2263
2264
"""
2265
cdef bint bit = True
2266
cdef bitset_t a
2267
2268
bitset_from_str(a, py_a)
2269
bitset_set_first_n(a, n)
2270
print "a.set_first_n(n) ", bitset_string(a)
2271
bitset_free(a)
2272
2273
2274
def test_bitset_remove(py_a, long n):
2275
"""
2276
Test the bitset_remove function.
2277
2278
TESTS::
2279
2280
sage: from sage.misc.bitset import test_bitset_remove
2281
sage: test_bitset_remove('01', 0)
2282
Traceback (most recent call last):
2283
...
2284
KeyError: 0L
2285
sage: test_bitset_remove('01', 1)
2286
a 01
2287
a.size 2
2288
a.limbs 1
2289
n 1
2290
a.remove(n) 00
2291
"""
2292
cdef bitset_t a
2293
bitset_from_str(a, py_a)
2294
2295
print "a", bitset_string(a)
2296
print "a.size", a.size
2297
print "a.limbs", a.limbs
2298
print "n", n
2299
2300
bitset_remove(a, n)
2301
print "a.remove(n) ", bitset_string(a)
2302
2303
bitset_free(a)
2304
2305
2306
def test_bitset_pop(py_a):
2307
"""
2308
Tests for the bitset_pop function.
2309
2310
TESTS::
2311
2312
sage: from sage.misc.bitset import test_bitset_pop
2313
sage: test_bitset_pop('0101')
2314
a.pop() 1
2315
new set: 0001
2316
sage: test_bitset_pop('0000')
2317
Traceback (most recent call last):
2318
...
2319
KeyError: 'pop from an empty set'
2320
"""
2321
cdef bitset_t a
2322
bitset_from_str(a, py_a)
2323
i = bitset_pop(a)
2324
print "a.pop() ", i
2325
print "new set: ", bitset_string(a)
2326
bitset_free(a)
2327
2328
2329
def test_bitset_unpickle(data):
2330
"""
2331
This (artificially) tests pickling of bitsets across systems.
2332
2333
INPUT:
2334
2335
- ``data`` -- A tuple of data as would be produced by the internal, Cython-only, method ``bitset_pickle``.
2336
2337
OUTPUT:
2338
2339
A list form of the bitset corresponding to the pickled data.
2340
2341
EXAMPLES:
2342
2343
We compare 64-bit and 32-bit encoding. Both should unpickle on any system::
2344
2345
sage: from sage.misc.bitset import test_bitset_unpickle
2346
sage: test_bitset_unpickle((0, 100, 2, 8, (33, 6001)))
2347
[0, 5, 64, 68, 69, 70, 72, 73, 74, 76]
2348
sage: test_bitset_unpickle((0, 100, 4, 4, (33, 0, 6001, 0)))
2349
[0, 5, 64, 68, 69, 70, 72, 73, 74, 76]
2350
"""
2351
cdef bitset_t bs
2352
bitset_init(bs, 1)
2353
bitset_unpickle(bs, data)
2354
L = bitset_list(bs)
2355
bitset_free(bs)
2356
return L
2357
2358