Skip to content
Snippets Groups Projects
Commit d09eeeab authored by Radek Hušek's avatar Radek Hušek Committed by Radek Hušek
Browse files

It compiles! :-)

parent bf35047c
No related branches found
No related tags found
No related merge requests found
.*.swp
groupConnectivity.so
Makefile 0 → 100644
default: groupConnectivity.so clean_obj
groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py
python setup.py build_ext
cp build/lib*/groupConnectivity.so .
clean_obj:
rm -f *.o groupConnectivity.cpp
rm -rf build
clean: clean_obj
rm -f groupConnectivity.so
......@@ -9,6 +9,8 @@ template < typename T_ > struct Name { \
enum { size = Size }; \
static T plus(T a, T b) { return Plus; } \
static T negate(T a) { return Negate; } \
static T multiply(T a, T b) { return Multiply; } \
static const T one = One; \
static const T zero = 0; \
}
......@@ -23,17 +25,18 @@ struct AbstractTester {
bool isConnected;
std::vector<size_t> classes;
typedef unsigned EdgeId;
typedef int EdgeId;
typedef int DirectedEdgeId;
virtual void init(
int edges,
std::vector<EdgeId> spanningTree,
std::vector< std::vector<DirectedEdgeId> > elementaryCycles
);
virtual bool run();
) =0;
virtual bool run() =0;
virtual ~AbstractTester() {}
}
};
template < typename Ring_ >
struct Tester : public AbstractTester {
......@@ -53,21 +56,46 @@ struct Tester : public AbstractTester {
size_t numForb;
int edges;
std::vector<EdgeId> classEdges;
std::vector< std::pair<EdgeId, Mapping> > nonClassEdges;
virtual void init(
int edges_,
std::vector<EdgeId> spanningTree,
std::vector< std::vector<DirectedEdgeId> > elementaryCycles
) {
edges = edges_;
numForb = 1;
while (edges_-- > 0) numForb *= (Ring::size - 1);
size_t num_classes = 1;
edges_ = spanningTree.size();
while (edges_-- > 0) num_classes *= Ring::size;
std::vector<size_t> C(num_classes, 0);
C.swap(classes);
for (auto e : spanningTree)
classEdges.push_back(e - 1);
for (const auto& elemCycle : elementaryCycles) {
nonClassEdges.push_back(std::make_pair(elemCycle[0] - 1, Mapping(edges, 0)));
Mapping &map = nonClassEdges.back().second;
for (auto edge : elemCycle) {
bool neg = (edge < 0);
edge = neg ? -edge : edge;
edge -= 1;
map[edge] = neg ? Ring::one : Ring::negate(Ring::one);
}
}
}
Mapping& unpack(size_t index, Mapping& ret) {
size_t m = Ring::size - 1;
for (size_t i = 0; i < G.edges(); i++) {
for (size_t i = 0; i < edges; i++) {
ret[i] = (index % m) + 1;
index /= m;
}
......@@ -97,7 +125,7 @@ struct Tester : public AbstractTester {
virtual bool run() {
Mapping forb(G.edges(), 0);
Mapping forb(edges, 0);
for (size_t i = 0; i < numForb; i++)
classes[pack(cannonize(unpack(i, forb)))]++;
......@@ -108,7 +136,7 @@ struct Tester : public AbstractTester {
}
virtual ~Tester() {}
}
};
#endif
from libcpp.vector cimport vector
cdef extern from "group-connectivity.h" namespace "Ring":
cdef cppclass Z4[T]: pass
cdef cppclass Z2_2[T]: pass
cdef extern from "group-connectivity.h":
cdef cppclass AbstractTester:
bool isConnected
vector[size_t] classes
void init(vector[unsigned], vector[vector[int]])
bool run()
cdef cppclass Tester[T]: pass
def groupConnectivityTest(G, group = "Z4"):
st = G.min_spanning_tree()
cdef AbstractTester* tester = NULL
if group == "Z4": tester = new Tester[Z4[unsigned]]
elif group == "Z2_2": tester = new Tester[Z2_2[unsigned]]
assert(tester != NULL)
tester.init()
ret = tester.run()
classes = tester.classes
del tester
return (ret, classes)
from libcpp.vector cimport vector
from libcpp cimport bool, pair
from sage.graphs.graph import Graph
cdef extern from "group-connectivity.h" namespace "Ring":
cdef cppclass Z4[T]:
pass
cdef cppclass Z2_2[T]:
pass
cdef extern from "group-connectivity.h":
cdef cppclass AbstractTester:
bool isConnected
vector[size_t] classes
void init(int, vector[int], vector[vector[int]])
bool run()
cdef cppclass Tester[T](AbstractTester):
pass
def pathToEdges(G, path):
ret = []
u = path[0]
for v in path[1:]:
mul = 1
if u > v: mul = -1
ret.append(mul * G.edge_label(u, v))
u = v
return ret
def testGroupConnectivity(G, group = "Z4", debug = False):
cdef AbstractTester* tester = NULL
if group == "Z4":
tester = new Tester[Z4[int]]()
elif group == "Z2_2":
tester = new Tester[Z2_2[int]]()
assert(tester != NULL)
i = 1
for (u, v, _) in G.edge_iterator():
G.set_edge_label(u, v, i)
i += 1
spanningTree = Graph(G.min_spanning_tree())
elemCycles = [
[ l ] + pathToEdges(G, spanningTree.shortest_path(u, v))
for (u, v, l) in set(G.edge_iterator()) - set(spanningTree.edge_iterator())
]
if debug:
print "Spanning Tree: ", [ l for (_, _, l) in spanningTree.edge_iterator() ]
print "Elementary cycles: ", elemCycles
tester.init(G.num_edges(), [ l for (_, _, l) in spanningTree.edge_iterator() ], elemCycles)
ret = tester.run()
classes = tester.classes
del tester
return (ret, classes)
setup.py 0 → 100644
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
setup(
name='FFtester',
version='1.0',
ext_modules = cythonize([
Extension("groupConnectivity",
sources = ["groupConnectivity.pyx"],
language="c++",
extra_compile_args=["-std=gnu++11", "-O2"]
)
])
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment