Interpolated Lookup Tables in Python
Normally there are all kinds of aspects to a simulation that are driven by mathematical functions, like gravity, momentum, population growth rates, economic trends, etc. However, mathematical functions can be difficult to tweak, and I’m finding it much easier to use lookup tables instead. This makes it much easier to make slight modifications: rather than adding additional terms to a function, I just have to modify the values in a table.
I wrapped up the logic for storing a table of points and providing interpolated values between those points into a Python class. Using Python’s __getitem__ method lets my object behave like an array, so I can just index into it when I need a value. Here’s the class:
class InterpolatedArray(object):
"""An array-like object that provides
interpolated values between set points."""
def __init__(self, points):
self.points = sorted(points)
def __getitem__(self, x):
if x < self.points[0][0] or x > self.points[-1][0]:
raise ValueError
lower_point, upper_point = self._GetBoundingPoints(x)
return self._Interpolate(x, lower_point, upper_point)
def _GetBoundingPoints(self, x):
"""Get the lower/upper points that bound x."""
lower_point = None
upper_point = self.points[0]
for point in self.points[1:]:
lower_point = upper_point
upper_point = point
if x <= upper_point[0]:
break
return lower_point, upper_point
def _Interpolate(self, x, lower_point, upper_point):
"""Interpolate a Y value for x given lower & upper
bounding points."""
slope = (float(upper_point[1] - lower_point[1]) /
(upper_point[0] - lower_point[0]))
return lower_point[1] + (slope * (x - lower_point[0]))
You use it like this:
points = ((1, 0), (5, 10), (10, 0)) table = InterpolatedArray(points) print table[1] print table[3.2] print table[7]
Here are some examples of the kinds of curves you can easily make:
points = [(0, 0), (2, 9.5), (4, 8.5), (6, 4), (8, 1), (10, 0)]
points = [(0, 10), (2, 10), (4, 9), (6, 7), (8, 4), (10, 0)]
points = [(0, 0), (2, 0), (4, 1.5), (6, 8.5), (8, 10), (10, 10)]
Feel free to use this in your own projects.
December 11th, 2008 at 6:17 pm
[...] understand more about how lookup tables work, or don’t want to install SciPy, check out this interpolated lookup table class. I wouldn’t use it for serious math, since it doesn’t use Numpy and is probably not [...]
December 12th, 2008 at 12:35 pm
Mark,
I recently found your interpolated lookup table class. I ended up using the interp1d class from SciPy, but I like your solution because it clearly illustrates how a lookup table works (and doesn’t require SciPy). Check out my full explanation at
http://www.shocksolution.com/2008/12/11/a-lookup-table-for-fast-python-math/
December 13th, 2008 at 2:08 pm
I didn’t realize SciPy had such a thing (although perhaps I should have guessed). Thanks for pointing it out!