diff --git a/interp/baker/__init__.py b/interp/baker/__init__.py index 4b4b3c9..b60139f 100644 --- a/interp/baker/__init__.py +++ b/interp/baker/__init__.py @@ -2,6 +2,9 @@ import sys import numpy as np +from functools import wraps +import itertools + import logging log = logging.getLogger('interp') @@ -99,7 +102,7 @@ def get_error(phi, R, S, order = 2): B = [] # baker eq 9 w = [] # baker eq 11 - p = pattern(order, len(phi), offset = -1) + p = pattern(len(phi), order) log.info("pattern: %s" % p) for (s,q) in zip(S.verts, S.q): @@ -183,42 +186,74 @@ def run_baker(X, R, S, order=2): return answer -def _boxings(n, k): - """\ - source for this function: - http://old.nabble.com/Simple-combinatorics-with-Numpy-td20086915.html - http://old.nabble.com/Re:-Simple-combinatorics-with-Numpy-p20099736.html - """ - seq, i = [n] * k + [0], k - while i: - yield tuple(seq[i] - seq[i+1] for i in xrange(k)) - i = seq.index(0) - 1 - seq[i:k] = [seq[i] - 1] * (k-i) - -def _samples_ur(items, k, offset = 0): - """Returns k unordered samples (with replacement) from items.""" - n = len(items) - for sample in _boxings(k, n): - selections = [[items[i]]*count for i,count in enumerate(sample)] - yield tuple([x + offset for sel in selections for x in sel]) - def memoize(f): """ - I only cache on power and phicount; I figure that one should stick to a - particular offset throughout one's codebase. + for more information on what I'm doing here, + please read: + + http://en.wikipedia.org/wiki/Memoize """ cache = {} + @wraps(f) def memf(*x, **kargs): if x not in cache: cache[x] = f(*x, **kargs) return cache[x] return memf +def combinations_with_replacement(iterable, r): + """ + What I really need for the pattern function only + exists in python 2.7 and greater. The docs suggest + the implementation in this function as a + replacement. + + see: http://docs.python.org/library/itertools.html#itertools.combinations_with_replacement + """ + pool = tuple(iterable) + n = len(pool) + for indices in itertools.product(range(n), repeat=r): + if sorted(indices) == list(indices): + yield tuple(pool[i] for i in indices) + @memoize -def pattern(power, phicount, offset = 0): - log.debug("(power = %s, phicount = %s)" % (power, phicount)) - r = [] - for i in _samples_ur(range(1, phicount + 1), power, offset): - if not len(set(i)) == 1: - r.append(i) - return r +def pattern(simplex_size, nu): + """ + my useful docstring + """ + log.debug("pattern: simplex: %d, order: %d" % (simplex_size, nu)) + return [i for i in combinations_with_replacement(xrange(simplex_size), nu) if len(set(i)) != 1] + +if __name__ == '__main__': + print len(pattern(3, 2)), pattern(3, 2) + print len(pattern(4, 2)), pattern(4, 2) + + print len(pattern(3, 3)), pattern(3, 3) + print len(pattern(4, 3)), pattern(4, 3) + + print len(pattern(3, 4)), pattern(3, 4) + print len(pattern(4, 4)), pattern(4, 4) + print len(pattern(3, 2)), pattern(3, 2) + print len(pattern(4, 2)), pattern(4, 2) + + print len(pattern(3, 3)), pattern(3, 3) + print len(pattern(4, 3)), pattern(4, 3) + + print len(pattern(3, 4)), pattern(3, 4) + print len(pattern(4, 4)), pattern(4, 4) + print len(pattern(3, 2)), pattern(3, 2) + print len(pattern(4, 2)), pattern(4, 2) + + print len(pattern(3, 3)), pattern(3, 3) + print len(pattern(4, 3)), pattern(4, 3) + + print len(pattern(3, 4)), pattern(3, 4) + print len(pattern(4, 4)), pattern(4, 4) + print len(pattern(3, 2)), pattern(3, 2) + print len(pattern(4, 2)), pattern(4, 2) + + print len(pattern(3, 3)), pattern(3, 3) + print len(pattern(4, 3)), pattern(4, 3) + + print len(pattern(3, 4)), pattern(3, 4) + print len(pattern(4, 4)), pattern(4, 4) diff --git a/test/pattern.py b/test/pattern.py index f21bc87..f55b067 100644 --- a/test/pattern.py +++ b/test/pattern.py @@ -13,35 +13,35 @@ class Test(unittest.TestCase): from interp.baker import pattern def test_baker_eq_8(self): - b = sorted([tuple(sorted(i)) for i in ((1,2),(2,3),(3,1))]) - p = sorted(pattern(power = 2, phicount = 3)) + b = sorted([tuple(sorted(i)) for i in ((0,1),(1,2),(2,0))]) + p = sorted(pattern(3,2)) self.assertEqual(b,p) def test_baker_eq_17(self): - b = sorted([tuple(sorted(i)) for i in ((1,2,2), (1,3,3), (2,1,1), (2,3,3), (3,1,1), (3,2,2), (1,2,3))]) - p = sorted(pattern(power = 3, phicount = 3)) + b = sorted([tuple(sorted(i)) for i in ((0,1,1), (0,2,2), (1,0,0), (1,2,2), (2,0,0), (2,1,1), (0,1,2))]) + p = sorted(pattern(3,3)) self.assertEqual(b,p) def test_baker_eq_15(self): b = sorted([tuple(sorted(i)) for i in ( - (1,2), (1,3), (1,4), - (2,3), (2,4), (3,4))]) + (0,1), (0,2), (0,3), + (1,2), (1,3), (2,3))]) - p = sorted(pattern(power = 2, phicount = 4)) + p = sorted(pattern(4,2)) self.assertEqual(b,p) def test_smcquay_(self): b = sorted([tuple(sorted(i)) for i in ( - (1,2,3), (2,3,4), (1,2,4), (1,3,4), - (1,1,2), (1,2,2), - (2,3,3), (2,2,3), + (0,1,2), (1,2,3), (0,1,3), (0,2,3), + (0,0,1), (0,1,1), + (1,2,2), (1,1,2), + (0,2,2), (0,0,2), (1,3,3), (1,1,3), - (2,4,4), (2,2,4), - (3,3,4), (3,4,4), - (1,4,4), (1,1,4))]) + (2,2,3), (2,3,3), + (0,3,3), (0,0,3))]) - p = sorted(pattern(power = 3, phicount = 4)) + p = sorted(pattern(4,3)) self.assertEqual(b,p)