replaced answer with a namedtuple

This commit is contained in:
Stephen M. McQuay 2011-09-17 15:39:01 -06:00
parent 837a72b246
commit 0577356cd7
8 changed files with 94 additions and 82 deletions

View File

@ -1,8 +1,9 @@
import numpy as np from collections import namedtuple
from functools import wraps from functools import wraps
import itertools import itertools
import numpy as np
import interp import interp
AGGRESSIVE_ERROR_SOLVE = True AGGRESSIVE_ERROR_SOLVE = True
@ -10,6 +11,8 @@ RAISE_PATHOLOGICAL_EXCEPTION = False
__version__ = interp.__version__ __version__ = interp.__version__
Answer = namedtuple("Answer", ['qlin', 'final', 'error', 'abc'])
def get_phis(X, R): def get_phis(X, R):
""" """
@ -124,7 +127,7 @@ def get_error(phi, R, R_q, S, S_q, order=2):
return error_term, abc return error_term, abc
def run_baker(X, R, R_q, S, S_q, order=2): def interpolate(X, R, R_q, S=None, S_q=None, order=2):
""" """
This is the main function to call to get an interpolation to X from the This is the main function to call to get an interpolation to X from the
input meshes input meshes
@ -132,23 +135,22 @@ def run_baker(X, R, R_q, S, S_q, order=2):
X -- the destination point X -- the destination point
R = Simplex R = Simplex
R_q = q values at R
S = extra points S = extra points
S_q = q values at S
order - order of interpolation - 1
""" """
answer = { qlin=None
'qlin': None, error_term=None
'error': None, final=None
'final': None, abc={}
}
# calculate values only for the simplex triangle # calculate values only for the simplex triangle
phi, qlin = qlinear(X, R, R_q) phi, qlin = qlinear(X, R, R_q)
if order == 1: if order in xrange(2, 11) and S:
answer['qlin'] = qlin
answer['final'] = qlin
return answer
elif order in xrange(2, 11):
error_term, abc = get_error(phi, R, R_q, S, S_q, order) error_term, abc = get_error(phi, R, R_q, S, S_q, order)
# if a pathological vertex configuration was encountered and # if a pathological vertex configuration was encountered and
@ -157,20 +159,13 @@ def run_baker(X, R, R_q, S, S_q, order=2):
if (error_term is None) and (abc is None): if (error_term is None) and (abc is None):
if RAISE_PATHOLOGICAL_EXCEPTION: if RAISE_PATHOLOGICAL_EXCEPTION:
raise np.linalg.LinAlgError("Pathological Vertex Config") raise np.linalg.LinAlgError("Pathological Vertex Config")
answer['qlin'] = qlin
answer['final'] = qlin
return answer
else: else:
final = qlin + error_term
elif order not in xrange(2,11):
raise Exception('unsupported order "%d" for baker method' % order) raise Exception('unsupported order "%d" for baker method' % order)
q_final = qlin + error_term
answer['qlin'] = qlin return Answer(qlin=qlin, error=error_term, final=final, abc=abc)
answer['error'] = error_term
answer['final'] = q_final
answer['abc'] = abc
return answer
def memoize(f): def memoize(f):

View File

@ -6,7 +6,7 @@ from xml.dom.minidom import Document
import numpy as np import numpy as np
from scipy.spatial import KDTree from scipy.spatial import KDTree
from interp.baker import run_baker from interp.baker import interpolate
from interp.baker import get_phis from interp.baker import get_phis
import interp import interp
@ -136,9 +136,9 @@ class grid(object):
return (r_mesh, s_mesh) return (r_mesh, s_mesh)
def run_baker(self, X, order=2, extra_points=3): def interpolate(self, X, order=2, extra_points=3):
(R, S) = self.get_simplex_and_nearest_points(X, extra_points) (R, S) = self.get_simplex_and_nearest_points(X, extra_points)
answer = run_baker(X, R, S, order) answer = interpolate(X, R, S, order)
return answer return answer
def for_qhull_generator(self): def for_qhull_generator(self):

View File

@ -45,6 +45,10 @@ def baker_exact_3D(X):
np.sin(z * np.pi / 2.0)), 2) np.sin(z * np.pi / 2.0)), 2)
return answer return answer
def exact_me(X, f):
a = np.array([f(i) for i in X])
return a
def friendly_exact_3D(X): def friendly_exact_3D(X):
x, y, z = X x, y, z = X
@ -67,6 +71,9 @@ def improved_answer(answer, exact):
else: else:
return False return False
def identical_points(a,b):
return all(set(j[i] for j in a) \
== set(j[i] for j in b) for i in xrange(len(a[0])))
def improved(qlin, err, final, exact): def improved(qlin, err, final, exact):
if np.abs(final - exact) <= np.abs(qlin - exact): if np.abs(final - exact) <= np.abs(qlin - exact):

View File

@ -21,4 +21,4 @@ if __name__ == '__main__':
] ]
for test in tests: for test in tests:
unittest.TextTestRunner(verbosity=3).run(test) unittest.TextTestRunner(verbosity=1).run(test)

View File

@ -3,6 +3,7 @@
import unittest import unittest
from interp import baker from interp import baker
from interp.baker import Answer
class Test(unittest.TestCase): class Test(unittest.TestCase):
@ -68,6 +69,17 @@ class Test(unittest.TestCase):
self.assertAlmostEqual(result, right_answer) self.assertAlmostEqual(result, right_answer)
def testRunBaker_linear(self):
size_of_simplex = 3
R, R_q = (self.all_points[:size_of_simplex],
self.q[:size_of_simplex])
answer = baker.interpolate(self.X, R, R_q)
good_answer = Answer(qlin=0.5, final=None, error=None, abc={})
self.assertEqual(answer, good_answer)
def testRunBaker_1(self): def testRunBaker_1(self):
size_of_simplex = 3 size_of_simplex = 3
extra_points = 3 extra_points = 3
@ -79,11 +91,11 @@ class Test(unittest.TestCase):
+ extra_points], + extra_points],
self.q[size_of_simplex:size_of_simplex + extra_points]) self.q[size_of_simplex:size_of_simplex + extra_points])
answer = baker.run_baker(self.X, R, R_q, S, S_q) answer = baker.interpolate(self.X, R, R_q, S, S_q)
a = answer['abc'][0] a = answer.abc[0]
b = answer['abc'][1] b = answer.abc[1]
c = answer['abc'][2] c = answer.abc[2]
self.assertEqual(sorted((a, b, c)), sorted((0, 0.0, 1 / 3.))) self.assertEqual(sorted((a, b, c)), sorted((0, 0.0, 1 / 3.)))
@ -97,9 +109,9 @@ class Test(unittest.TestCase):
+ extra_points], + extra_points],
self.q[size_of_simplex:size_of_simplex + extra_points]) self.q[size_of_simplex:size_of_simplex + extra_points])
answer = baker.run_baker(self.X, R, R_q, S, S_q) answer = baker.interpolate(self.X, R, R_q, S, S_q)
a, b, c = sorted(answer['abc']) a, b, c = sorted(answer.abc)
aa, bb, cc = sorted((2 / 3.0, 2 / 3.0, 1 / 3.0)) aa, bb, cc = sorted((2 / 3.0, 2 / 3.0, 1 / 3.0))
self.assertAlmostEqual(a, aa) self.assertAlmostEqual(a, aa)
@ -115,11 +127,11 @@ class Test(unittest.TestCase):
S, S_q = (self.all_points[size_of_simplex:size_of_simplex \ S, S_q = (self.all_points[size_of_simplex:size_of_simplex \
+ extra_points], + extra_points],
self.q[size_of_simplex:size_of_simplex + extra_points]) self.q[size_of_simplex:size_of_simplex + extra_points])
answer = baker.run_baker(self.X, R, R_q, S, S_q) answer = baker.interpolate(self.X, R, R_q, S, S_q)
a = answer['abc'][0] a = answer.abc[0]
b = answer['abc'][1] b = answer.abc[1]
c = answer['abc'][2] c = answer.abc[2]
a, b, c = sorted((a, b, c)) a, b, c = sorted((a, b, c))
aa, bb, cc = sorted((13 / 14., 2 / 7., 15 / 14.)) aa, bb, cc = sorted((13 / 14., 2 / 7., 15 / 14.))
@ -137,11 +149,11 @@ class Test(unittest.TestCase):
S, S_q = (self.all_points[size_of_simplex:size_of_simplex \ S, S_q = (self.all_points[size_of_simplex:size_of_simplex \
+ extra_points], + extra_points],
self.q[size_of_simplex:size_of_simplex + extra_points]) self.q[size_of_simplex:size_of_simplex + extra_points])
answer = baker.run_baker(self.X, R, R_q, S, S_q) answer = baker.interpolate(self.X, R, R_q, S, S_q)
a = answer['abc'][0] a = answer.abc[0]
b = answer['abc'][1] b = answer.abc[1]
c = answer['abc'][2] c = answer.abc[2]
a, b, c = sorted((a, b, c)) a, b, c = sorted((a, b, c))
aa, bb, cc = sorted((48 / 53.0, 15 / 53.0, 54 / 53.0)) aa, bb, cc = sorted((48 / 53.0, 15 / 53.0, 54 / 53.0))

View File

@ -77,7 +77,7 @@ class Test(unittest.TestCase):
self.phis, self.qlin = baker.qlinear(self.X, self.R, self.q) self.phis, self.qlin = baker.qlinear(self.X, self.R, self.q)
self.exact = exact_func(self.X) self.exact = exact_func(self.X)
self.answer = baker.run_baker(self.X, self.R, self.answer = baker.interpolate(self.X, self.R,
self.R_q, self.S, self.S_q) self.R_q, self.S, self.S_q)
def test_R_contains_X(self): def test_R_contains_X(self):
@ -86,22 +86,22 @@ class Test(unittest.TestCase):
def test_1(self): def test_1(self):
a, b, c, d, e, f = (0, 1, 1, 2, 2, 0) a, b, c, d, e, f = (0, 1, 1, 2, 2, 0)
err = calculate_error_term(self, a, b, c, d, e, f) err = calculate_error_term(self, a, b, c, d, e, f)
self.assertAlmostEqual(err, self.answer['error']) self.assertAlmostEqual(err, self.answer.error)
def test_swap_first_elements(self): def test_swap_first_elements(self):
a, b, c, d, e, f = (1, 0, 1, 2, 2, 0) a, b, c, d, e, f = (1, 0, 1, 2, 2, 0)
err = calculate_error_term(self, a, b, c, d, e, f) err = calculate_error_term(self, a, b, c, d, e, f)
self.assertAlmostEqual(err, self.answer['error']) self.assertAlmostEqual(err, self.answer.error)
def test_swap_two_pairs(self): def test_swap_two_pairs(self):
a, b, c, d, e, f = (1, 2, 0, 1, 2, 0) a, b, c, d, e, f = (1, 2, 0, 1, 2, 0)
err = calculate_error_term(self, a, b, c, d, e, f) err = calculate_error_term(self, a, b, c, d, e, f)
self.assertAlmostEqual(err, self.answer['error']) self.assertAlmostEqual(err, self.answer.error)
def test_swap_all_pairs(self): def test_swap_all_pairs(self):
a, b, c, d, e, f = (0, 2, 0, 1, 2, 1) a, b, c, d, e, f = (0, 2, 0, 1, 2, 1)
err = calculate_error_term(self, a, b, c, d, e, f) err = calculate_error_term(self, a, b, c, d, e, f)
self.assertAlmostEqual(err, self.answer['error']) self.assertAlmostEqual(err, self.answer.error)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -2,8 +2,7 @@
import unittest import unittest
from interp.baker import run_baker from interp.baker import interpolate
from interp.grid import contains from interp.grid import contains
@ -36,42 +35,42 @@ class Test(unittest.TestCase):
def test_RunBaker_1_extra_point(self, extra=1): def test_RunBaker_1_extra_point(self, extra=1):
S = self.g[3:3 + extra] S = self.g[3:3 + extra]
S_q = self.q[3:3 + extra] S_q = self.q[3:3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q, order=3) answer = interpolate(self.X, self.R, self.R_q, S, S_q, order=3)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
# expected failure ... # expected failure ...
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
def test_RunBaker_2_extra_point(self, extra=2): def test_RunBaker_2_extra_point(self, extra=2):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3:3 + extra] S_q = self.q[3:3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q, order=3) answer = interpolate(self.X, self.R, self.R_q, S, S_q, order=3)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
def test_RunBaker_3_extra_point(self, extra=3): def test_RunBaker_3_extra_point(self, extra=3):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3:3 + extra] S_q = self.q[3:3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q, order=3) answer = interpolate(self.X, self.R, self.R_q, S, S_q, order=3)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
def test_RunBaker_4_extra_point(self, extra=4): def test_RunBaker_4_extra_point(self, extra=4):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3:3 + extra] S_q = self.q[3:3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q, order=3) answer = interpolate(self.X, self.R, self.R_q, S, S_q, order=3)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
def test_RunBaker_5_extra_point(self, extra=5): def test_RunBaker_5_extra_point(self, extra=5):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3:3 + extra] S_q = self.q[3:3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q, order=3) answer = interpolate(self.X, self.R, self.R_q, S, S_q, order=3)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -2,8 +2,7 @@
import unittest import unittest
from interp.baker import run_baker from interp.baker import interpolate
from interp.grid import grid from interp.grid import grid
from interp.grid import contains from interp.grid import contains
@ -41,9 +40,9 @@ class Test(unittest.TestCase):
def test_RunBaker_1_extra_point(self, extra=1): def test_RunBaker_1_extra_point(self, extra=1):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3: 3 + extra] S_q = self.q[3: 3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q) answer = interpolate(self.X, self.R, self.R_q, S, S_q)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
#XXX: not sure about this one: #XXX: not sure about this one:
self.assertEqual(lin_err, final_err) self.assertEqual(lin_err, final_err)
@ -51,33 +50,33 @@ class Test(unittest.TestCase):
def test_RunBaker_2_extra_point(self, extra=2): def test_RunBaker_2_extra_point(self, extra=2):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3: 3 + extra] S_q = self.q[3: 3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q) answer = interpolate(self.X, self.R, self.R_q, S, S_q)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
def test_RunBaker_3_extra_point(self, extra=3): def test_RunBaker_3_extra_point(self, extra=3):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3: 3 + extra] S_q = self.q[3: 3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q) answer = interpolate(self.X, self.R, self.R_q, S, S_q)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
def test_RunBaker_4_extra_point(self, extra=4): def test_RunBaker_4_extra_point(self, extra=4):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3: 3 + extra] S_q = self.q[3: 3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q) answer = interpolate(self.X, self.R, self.R_q, S, S_q)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
def test_RunBaker_5_extra_point(self, extra=5): def test_RunBaker_5_extra_point(self, extra=5):
S = self.g[3: 3 + extra] S = self.g[3: 3 + extra]
S_q = self.q[3: 3 + extra] S_q = self.q[3: 3 + extra]
answer = run_baker(self.X, self.R, self.R_q, S, S_q) answer = interpolate(self.X, self.R, self.R_q, S, S_q)
lin_err = abs(self.exact - answer['qlin']) lin_err = abs(self.exact - answer.qlin)
final_err = abs(self.exact - answer['final']) final_err = abs(self.exact - answer.final)
self.assertTrue(lin_err >= final_err) self.assertTrue(lin_err >= final_err)
if __name__ == '__main__': if __name__ == '__main__':