-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_defect.pyx
94 lines (76 loc) · 3.74 KB
/
_defect.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# _defect.pyx: Cython bindings for the kitchen sink
# I wanted this stuff to be available under the package heirarchy '
# This provides a C++ implementation of the XorBasisBuilder class, which manages an RREF bit
# matrix for the purposes of building e.g. a cycle basis.
# XorBasisBuilder is currently a class with very limited offerings; it basically only offers
# precisely the functionality required by CycleBasisBuilder, and no more than that.
# (that is to say, perhaps it might be better named "CycleBasisBuilder_Impl" :P)
from libcpp.vector cimport vector
from libcpp.utility cimport pair
from cython.operator cimport dereference as deref, preincrement as inc
# Q: Why are you declaring meaningful names like `column_t` and `identity_t` and then not using them?
# A: They're just here for you, the reader. I had every intention of using them, but as it turns
# out, cython has trouble performing automatic list->vector conversion for vectors of custom types:
#
# cdef extern from *:
# ctypedef column_t X '__pyx_t_9cXorBasis_column_t'
# ^
# ------------------------------------------------------------
#
# vector.from_py:37:13: 'column_t' is not a type identifier
#
#
# Q: ...um, then why do you also define and use `uint`? Wouldn't that be similarly broken?
# A: Funny you ask, because no, `vector[uint]` works just fine! Though I highly suspect it isn't using
# my `uint`, but rather one that it managed to find defined somewhere else.
# Come to think of it, gee, I sure hope it has the same definition as mine...
#
# Q: Wait, you're not even sure that the `uint` it uses is the same as your `uint`? Holy smokes,
# Batman, that sounds dangerous! Why not just use `unsigned int`?
# A: Oh yeah, that. See, I also had trouble declaring a `vector[unsigned]` (something about `unsigned`
# not being a known type) or a `vector[vector[unsigned int]]` (expected `]`, found `int`).
#
# Q: Plan to bring these bugs up with the cython team?
# A: Eh... odds are 5% these bugs are legitimate, 95% I'm just a bonehead.
ctypedef unsigned uint
ctypedef unsigned column_t
ctypedef size_t identity_t
cdef extern from "defect/ext/xorbasis.h":
cdef cppclass _XorBasisBuilder:
_XorBasisBuilder()
size_t add(vector[uint])
vector[size_t] add_many(vector[vector[uint]])
pair[bint,size_t] add_if_linearly_independent(vector[uint])
vector[vector[size_t]] get_zero_sums()
# void remove_from_each_zero_sum(vector[size_t])
void remove_ids(vector[size_t])
# void remove_linearly_dependent_ids()
# bint has_linearly_dependent_rows()
cdef class XorBasisBuilder:
cdef _XorBasisBuilder *thisptr
def __cinit__(self):
self.thisptr = new _XorBasisBuilder()
def __dealloc__(self):
del self.thisptr
def add(self, row):
cdef vector[uint] vec = list(row)
return self.thisptr.add(vec)
def add_many(self, it):
cdef vector[vector[uint]] vec = list(list(x) for x in it)
return self.thisptr.add_many(vec)
def add_if_linearly_independent(self, row):
cdef vector[uint] vec = list(row)
cdef pair[bint,size_t] p = self.thisptr.add_if_linearly_independent(vec)
return (bool(p.first), p.second)
def get_zero_sums(self):
return self.thisptr.get_zero_sums()
# def remove_from_each_zero_sum(self, ids):
# cdef vector[size_t] vec = list(ids)
# self.thisptr.remove_from_each_zero_sum(vec)
# def get_linearly_dependent_ids(self):
# return self.thisptr.get_linearly_dependent_ids()
def remove_ids(self, it):
cdef vector[size_t] ids = list(it)
self.thisptr.remove_ids(ids)
# def remove_linearly_dependent_ids(self):
# self.thisptr.remove_linearly_dependent_ids()