annotate numerics/interpolation.py @ 4:097296d6132e

add interpolation
author Jeff Hammel <k0scist@gmail.com>
date Thu, 04 Sep 2014 08:21:10 -0700
parents
children 7517682843cb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
1 #!/usr/bin/env python
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
2
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
3
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
4 """
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
5 interpolation
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
6 """
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
7
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
8 __all__ = ['neighbors', 'linear_interpolation']
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
9
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
10 def neighbors(start, finish):
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
11 """
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
12 returns the neighbors in finish from start
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
13 assumes both are sorted
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
14 """
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
15 assert finish
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
16 index = 0
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
17 retval = []
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
18 for x in start:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
19 # endpoints
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
20 if x < finish[0]:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
21 retval.append((None, 0))
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
22 continue
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
23 if x > finish[-1]:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
24 retval.append((len(finish)-1, None))
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
25 continue
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
26 # traverse
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
27 try:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
28 while True:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
29 if x < finish[index] or x > finish[index+1]:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
30 index += 1
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
31 continue
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
32 else:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
33 break
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
34 retval.append((index, index+1))
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
35 except IndexError:
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
36 retval.append((len(finish)-2, len(finish)-1))
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
37
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
38 return retval
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
39
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
40
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
41 def linear_interpolation(data, points):
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
42 """
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
43 linearly interpolate data to points
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
44
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
45 data -- iterable of 2-tuples (or equivalent) of `x,y`
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
46 points -- `x`-values to interpolate to
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
47 """
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
48
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
49 # ensure we are sorted
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
50 data = sorted(data, key=lambda x: x[0])
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
51 points = sorted(points)
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
52
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
53 # get the neighbors
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
54 x = [value[0] for value in data]
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
55 nearest_neighbors = neighbors(points, x)
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
56
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
57 # we don't support endpoints yet; this is interpolation, not extrapolation
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
58 assert not any([(neighbor[0] is None or neighbor[1] is None)
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
59 for neighbor in nearest_neighbors])
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
60
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
61 retval = []
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
62 for index, (left, right) in enumerate(nearest_neighbors):
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
63 # linearly interpolate
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
64 ratio = (points[index] - data[left][0])/float(data[right][0] - data[left][0])
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
65 retval.append(ratio*data[right][1] + (1.-ratio)*data[left][1])
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
66 return retval
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
67
097296d6132e add interpolation
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
68