From 1e3cfb710678b319d79b31ec85b832e0542fa69d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radek=20Hu=C5=A1ek?= <PitelVonSacek@gmail.com>
Date: Wed, 9 Dec 2015 16:35:05 +0100
Subject: [PATCH] Change Mapping into a wrapper class

We split definition of Mapping into separate file.
We also change Mapping from std::vector<*> into
class wrapping std::vector<*>. This is prerequisite
for future specialized fast implementation of Mapping
for Z4 and Z2_2.
---
 fast-array.h         | 31 +++++++++++++++++++++++++++++++
 group-connectivity.h | 20 +++++---------------
 2 files changed, 36 insertions(+), 15 deletions(-)
 create mode 100644 fast-array.h

diff --git a/fast-array.h b/fast-array.h
new file mode 100644
index 0000000..7edb19b
--- /dev/null
+++ b/fast-array.h
@@ -0,0 +1,31 @@
+#ifndef __FAST_ARRAY_H__
+#define __FAST_ARRAY_H__
+
+template < typename Ring, size_t maxSize = 0 >
+struct Mapping {
+  typedef typename Ring::T T;
+  std::vector<T> data;
+
+  Mapping() {}
+
+  template < typename X >
+  Mapping(X x) : data(x.data) {}
+
+  Mapping(size_t size = 0, T val = 0) : data(size, val) {}
+  inline size_t size() const { return data.size(); }
+
+  inline T operator[] (size_t i) const { return data[i]; }
+  inline void assign(size_t i, T val) { data[i] = val; }
+
+  Mapping& combine(T alpha, T beta, const Mapping& b) {
+    Mapping &a = *this;
+    size_t size = a.size();
+    for (size_t i = 0; i < size; i++)
+      data[i] = Ring::plus(Ring::multiply(alpha, a.data[i]),
+                           Ring::multiply(beta, b.data[i]));
+    return a;
+  }
+};
+
+#endif
+
diff --git a/group-connectivity.h b/group-connectivity.h
index d059a16..379e80a 100644
--- a/group-connectivity.h
+++ b/group-connectivity.h
@@ -4,6 +4,7 @@
 #include <vector>
 #include "compileTimeOptions.h"
 #include "rings.h"
+#include "fast-array.h"
 
 
 typedef int EdgeId;
@@ -36,18 +37,7 @@ 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;
-  }
-
+  typedef ::Mapping<Ring> Mapping;
 
   size_t numForb;
   int edges;
@@ -82,7 +72,7 @@ struct Tester : public AbstractTester {
         bool neg = (edge < 0);
         edge = neg ? -edge : edge;
         edge -= 1;
-        map[edge] = neg ? Ring::one : Ring::negate(Ring::one);
+        map.assign(edge, neg ? Ring::one : Ring::negate(Ring::one));
       }
     }
   }
@@ -91,7 +81,7 @@ struct Tester : public AbstractTester {
     size_t m = Ring::size - 1;
 
     for (size_t i = 0; i < edges; i++) {
-      ret[i] = (index % m) + 1;
+      ret.assign(i, (index % m) + 1);
       index /= m;
     }
 
@@ -101,7 +91,7 @@ struct Tester : public AbstractTester {
   Mapping& cannonize(Mapping& map) {
     for (const auto &i : nonClassEdges) {
       if (map[i.first] != Ring::zero)
-        combine(Ring::one, map, map[i.first], i.second);
+        map.combine(Ring::one, map[i.first], i.second);
     }
 
     return map;
-- 
GitLab