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

init

parents
No related branches found
No related tags found
No related merge requests found
#ifndef __GROUP_CONNECTIVITY_H__
#define __GROUP_CONNECTIVITY_H__
namespace Ring {
#define MakeRing(Name, Size, Plus, Negate, Multiply, One) \
template < typename T_ > struct Name { \
typedef T_ T; \
enum { size = Size }; \
static T plus(T a, T b) { return Plus; } \
static T negate(T a) { return Negate; } \
static const T zero = 0; \
}
MakeRing(Z4, 4, (a + b) % 4, (4 - a) % 4, (a * b) % 4, 1);
MakeRing(Z2_2, 4, a^b, a, a&b, 3);
}
#include <vector>
struct AbstractTester {
bool isConnected;
std::vector<size_t> classes;
typedef unsigned EdgeId;
typedef int DirectedEdgeId;
virtual void init(
std::vector<EdgeId> spanningTree,
std::vector< std::vector<DirectedEdgeId> > elementaryCycles
);
virtual bool run();
virtual ~AbstractTester() {}
}
template < typename Ring_ >
struct Tester : public AbstractTester {
typedef Ring_ Ring;
typedef typename Ring::T T;
typedef std::vector<T> Mapping;
// combine(alpha, a, beta, b) calculates a = alpha * a + beta * b
Mapping& combine(T alpha, Mapping& a, T beta, const Mapping& b) {
size_t size = a.size();
for (size_t i = 0; i < size; i++)
a[i] = Ring::plus(Ring::multiply(alpha, a[i]),
Ring::multiply(beta, b[i]));
return a;
}
size_t numForb;
std::vector<EdgeId> classEdges;
std::vector< std::pair<EdgeId, Mapping> > nonClassEdges;
virtual void init(
std::vector<EdgeId> spanningTree,
std::vector< std::vector<DirectedEdgeId> > elementaryCycles
) {
}
Mapping& unpack(size_t index, Mapping& ret) {
size_t m = Ring::size - 1;
for (size_t i = 0; i < G.edges(); i++) {
ret[i] = (index % m) + 1;
index /= m;
}
return ret;
}
Mapping& cannonize(Mapping& map) {
for (const auto &i : nonClassEdges) {
if (map[i.first] != Ring::zero)
combine(Ring::one, map, map[i.first], i.second);
}
return map;
}
size_t pack(const Mapping& map) {
size_t index = 0;
for (auto i : classEdges) {
index *= Ring::size;
index += map[i];
}
return index;
}
virtual bool run() {
Mapping forb(G.edges(), 0);
for (size_t i = 0; i < numForb; i++)
classes[pack(cannonize(unpack(i, forb)))]++;
for (auto &c : classes) if (!c) return (isConnected = false);
return (isConnected = true);
}
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)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment