fixed the pattern function and the memoization thereof
This commit is contained in:
parent
08f898d83a
commit
2e7391f573
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user