[mathic] 10/62: Added BitTriangle (a triangle of bits) to Mathic.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Wed Apr 1 11:36:18 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository mathic.

commit 23e0b986052141e9f619e0b812642bfb9ce13b4a
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Mon Jul 9 20:09:59 2012 -0400

    Added BitTriangle (a triangle of bits) to Mathic.
---
 Makefile.am                | 21 ++++++------
 src/mathic.h               |  3 ++
 src/mathic/BitTriangle.cpp | 15 +++++++++
 src/mathic/BitTriangle.h   | 84 ++++++++++++++++++++++++++++++++++++++++++++++
 src/test/BitTriangle.cpp   | 70 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 183 insertions(+), 10 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 0787885..5707da7 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,14 +19,14 @@ AM_CXXFLAGS=-I$(top_srcdir)/src/
 libmathic_ at MATHIC_API_VERSION@_la_LIBADD= $(DEPS_LIBS)
 
 # the sources that are built to make libmathic.
-libmathic_ at MATHIC_API_VERSION@_la_SOURCES = src/mathic/Timer.cpp		\
-  src/mathic/ColumnPrinter.cpp src/mathic/DivMask.cpp					\
-  src/mathic/Action.cpp src/mathic/BoolParameter.cpp					\
-  src/mathic/CliParameter.cpp src/mathic/CliParser.cpp					\
-  src/mathic/ElementDeleter.cpp src/mathic/NameFactory.cpp				\
-  src/mathic/error.cpp src/mathic/HelpAction.cpp						\
-  src/mathic/IntegerParameter.cpp src/mathic/StringParameter.cpp		\
-  src/mathic/display.cpp
+libmathic_ at MATHIC_API_VERSION@_la_SOURCES = src/mathic/Timer.cpp	\
+  src/mathic/ColumnPrinter.cpp src/mathic/DivMask.cpp				\
+  src/mathic/Action.cpp src/mathic/BoolParameter.cpp				\
+  src/mathic/CliParameter.cpp src/mathic/CliParser.cpp				\
+  src/mathic/ElementDeleter.cpp src/mathic/NameFactory.cpp			\
+  src/mathic/error.cpp src/mathic/HelpAction.cpp					\
+  src/mathic/IntegerParameter.cpp src/mathic/StringParameter.cpp	\
+  src/mathic/display.cpp src/mathic/BitTriangle.cpp
 
 # The headers that libmathic installs.
 # Normally, automake strips the path from the files when installing them,
@@ -47,7 +47,8 @@ mathicB_include_HEADERS = src/mathic/Action.h src/mathic/Geobucket.h	\
   src/mathic/PackedKDTree.h src/mathic/DivFinder.h src/mathic/stdinc.h	\
   src/mathic/DivList.h src/mathic/StlSet.h src/mathic/DivMask.h			\
   src/mathic/StringParameter.h src/mathic/ElementDeleter.h				\
-  src/mathic/Timer.h src/mathic/error.h src/mathic/TourTree.h
+  src/mathic/Timer.h src/mathic/error.h src/mathic/TourTree.h			\
+  src/mathic/BitTriangle.h
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = build/autotools/mathic-$(MATHIC_API_VERSION).pc
@@ -94,4 +95,4 @@ unittest_LDFLAGS= $(top_builddir)/libmathic-$(MATHIC_API_VERSION).la
 
 test_LIBS=
 unittest_SOURCES=src/test/DivFinder.cpp src/test/gtestInclude.cpp	\
-src/test/testMain.cpp
+  src/test/testMain.cpp src/test/BitTriangle.cpp
diff --git a/src/mathic.h b/src/mathic.h
index d9ffb91..3c632e3 100755
--- a/src/mathic.h
+++ b/src/mathic.h
@@ -6,6 +6,9 @@
 #include "mathic/ElementDeleter.h"
 #include "mathic/error.h"
 
+// other data structures
+#include "mathic/BitTriangle.h"
+
 // divisor query data structures
 #include "mathic/DivList.h"
 #include "mathic/KDTree.h"
diff --git a/src/mathic/BitTriangle.cpp b/src/mathic/BitTriangle.cpp
new file mode 100755
index 0000000..4d739ca
--- /dev/null
+++ b/src/mathic/BitTriangle.cpp
@@ -0,0 +1,15 @@
+#include "stdinc.h"
+#include "BitTriangle.h"
+
+namespace mathic {
+  size_t BitTriangle::getMemoryUse() const
+  {
+	size_t sum = mColumns.capacity() * sizeof(mColumns.front());
+	const size_t stop = mColumns.size();
+	for (size_t i = 0; i != stop; ++i) {
+	  size_t const capacity = mColumns[i].capacity();
+	  sum += (capacity + 7) / 8; // 8 bits per byte rounded up
+	}
+	return sum;
+  }
+}
diff --git a/src/mathic/BitTriangle.h b/src/mathic/BitTriangle.h
new file mode 100755
index 0000000..3ab4070
--- /dev/null
+++ b/src/mathic/BitTriangle.h
@@ -0,0 +1,84 @@
+#ifndef MATHIC_BIT_TRIANGLE_GUARD
+#define MATHIC_BIT_TRIANGLE_GUARD
+
+#include "stdinc.h"
+#include <vector>
+
+namespace mathic {
+  // Object that stores a triangular 2-dimensional array of bits. For example:
+  //
+  // row
+  //  3|      
+  //  2|      1
+  //  1|    0 1
+  //  0|  0 0 0
+  //    -------
+  //    0 1 2 3 column
+  //
+  // A bit is addressed by a pair (column, row) where the column goes first.
+  // All valid address pairs have 0 <= row < column < columnCount().
+  // Columns can be added dynamically.
+  class BitTriangle {
+  public:
+	// Returns how many columns the triangle has
+	size_t columnCount() const {return mColumns.size();}
+
+	// Returns true if there are no columns in the triangle
+	bool empty() const {return mColumns.empty();}
+
+	// Adds a new column of the triangle. This increases columnCount() by
+	// one, and the index of the new column is the previous value of
+	// columnCount(). The new bits are all set to false initially.
+	void addColumn() {
+	  size_t const oldSize = mColumns.size();
+	  mColumns.resize(oldSize + 1);
+	  mColumns[oldSize].resize(oldSize);
+	}
+
+	// Returns the bit in the given column and row. As this is a triangle it
+	// must be true that row < column.
+	bool bit(size_t column, size_t row) const {
+	  MATHIC_ASSERT(column < columnCount());
+	  MATHIC_ASSERT(row < column);
+	  return mColumns[column][row];
+	}
+
+	// As bit(), but uses max(x,y) as the column and min(x,y) as the
+	// row.
+	bool bitUnordered(size_t x, size_t y) const {
+	  MATHIC_ASSERT(x < columnCount());
+	  MATHIC_ASSERT(y < columnCount());
+	  MATHIC_ASSERT(x != y);
+	  if (x < y)
+		std::swap(x, y);
+	  return bit(x, y);
+	}
+
+	// Sets the bit in the given column and row. As this is a triangle
+	// it must be true that column >= row.
+	void setBit(size_t column, size_t row, bool value) {
+	  MATHIC_ASSERT(column < columnCount());
+	  MATHIC_ASSERT(row < column);
+	  mColumns[column][row] = value;
+	}
+
+	// As setBit, but uses max(x,y) as the column and min(x,y) as the
+	// row.
+	void setBitUnordered(size_t x, size_t y, bool value) {
+	  MATHIC_ASSERT(x < columnCount());
+	  MATHIC_ASSERT(y < columnCount());
+	  MATHIC_ASSERT(x != y);
+	  if (x < y)
+		std::swap(x, y);
+	  setBit(x, y, value);
+	}
+
+	size_t getMemoryUse() const;
+
+  private:
+	// @todo: use one big array instead of an array of arrays.
+	std::vector<std::vector<bool> > mColumns;
+  };
+}
+
+#endif
diff --git a/src/test/BitTriangle.cpp b/src/test/BitTriangle.cpp
new file mode 100755
index 0000000..3e1bf0a
--- /dev/null
+++ b/src/test/BitTriangle.cpp
@@ -0,0 +1,70 @@
+#include "mathic/BitTriangle.h"
+#include <gtest/gtest.h>
+
+TEST(BitTriangle, NoOp) {
+  mathic::BitTriangle tri;
+};
+
+TEST(BitTriangle, emptyAndColumnCount) {
+  mathic::BitTriangle tri;
+  ASSERT_TRUE(tri.empty());
+  ASSERT_EQ(0u, tri.columnCount());
+
+  tri.addColumn();
+  ASSERT_FALSE(tri.empty());
+  ASSERT_EQ(1u, tri.columnCount());
+
+  tri.addColumn();
+  ASSERT_FALSE(tri.empty());
+  ASSERT_EQ(2u, tri.columnCount());
+}
+
+TEST(BitTriangle, getSetBit) {
+  size_t const colCount = 20; // consider colCount columns
+  size_t const modPattern = 11;
+  mathic::BitTriangle tri;
+  for (size_t col = 0; col < colCount; ++col) {
+	tri.addColumn();
+	for (size_t row = 0; row < col; ++row) {
+	  ASSERT_FALSE(tri.bit(col, row));
+	  ASSERT_FALSE(tri.bitUnordered(col, row));
+	  ASSERT_FALSE(tri.bitUnordered(row, col));
+
+	  tri.setBit(col, row, true);
+	  ASSERT_TRUE(tri.bit(col, row));
+	  ASSERT_TRUE(tri.bitUnordered(col, row));
+	  ASSERT_TRUE(tri.bitUnordered(row, col));
+
+	  tri.setBitUnordered(col, row, false);
+	  ASSERT_FALSE(tri.bit(col, row));
+	  ASSERT_FALSE(tri.bitUnordered(col, row));
+	  ASSERT_FALSE(tri.bitUnordered(row, col));
+
+	  tri.setBitUnordered(row, col, true);
+	  ASSERT_TRUE(tri.bit(col, row));
+	  ASSERT_TRUE(tri.bitUnordered(col, row));
+	  ASSERT_TRUE(tri.bitUnordered(row, col));
+
+	  // set bits mod 11 since 3 is relatively prime to 2
+	  // so any mod 2^k pattern is avoided and 11>8 so we do
+	  // get bytes that are all ones.
+	  bool const value = ((row + col) % modPattern != 0);
+
+	  tri.setBit(col, row, value);
+	  ASSERT_EQ(value, tri.bit(col, row));
+	  ASSERT_EQ(value, tri.bitUnordered(col, row));
+	  ASSERT_EQ(value, tri.bitUnordered(row, col));
+	}
+  }
+  ASSERT_EQ(colCount, tri.columnCount());
+
+  // check that the pattern of bits is preserved
+  for (size_t col = 0; col < colCount; ++col) {
+	for (size_t row = 0; row < col; ++row) {
+	  bool const value = ((row + col) % 11 != 0);
+	  ASSERT_EQ(value, tri.bit(col, row));
+	  ASSERT_EQ(value, tri.bitUnordered(col, row));
+	  ASSERT_EQ(value, tri.bitUnordered(row, col));
+	}
+  }
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathic.git



More information about the debian-science-commits mailing list