22
33[ ![ Build Status] ( https://travis-ci.org/EconForge/interpolation.py.svg?branch=master )] ( https://travis-ci.org/EconForge/interpolation.py )
44
5- This library provides fast numba-accelerated interpolation routines
6- for the following cases:
5+ The library contains:
6+ - splines.* : fast numba-compatible multilinear and cubic interpolation
7+ - multilinear.* : fast numba-compatible multilinear interpolation (alternative implementation)
8+ - smolyak.* : smolyak polinomials
9+ - complete polynomials
710
8- ## multilinear and cubic splines in any dimension
11+ ## multilinear and cubic interpolation
12+
13+ Fast numba-accelerated interpolation routines
14+ for multilinear and cubic interpolation, with any number of dimensions.
15+ Several interfaces are provided.
16+
17+ ### eval_linear
18+
19+ Preferred interface for multilinear interpolation. It can interpolate on uniform
20+ and nonuniform cartesian grids. Several extrapolation options are available.
921
10- Here is an example in 3 dimensions:
1122
1223``` python
13- from interpolation.splines import LinearSpline, CubicSpline
14- a = np.array([0.0 ,0.0 ,0.0 ]) # lower boundaries
15- b = np.array([1.0 ,1.0 ,1.0 ]) # upper boundaries
16- orders = np.array([50 ,50 ,50 ]) # 50 points along each dimension
17- values = np.random.random(orders) # values at each node of the grid
18- S = np.random.random((10 ** 6 ,3 )) # coordinates at which to evaluate the splines
24+ import numpy as np
1925
20- # multilinear
21- lin = LinearSpline(a,b,orders,values)
22- V = lin(S)
23- # cubic
24- spline = CubicSpline(a,b,orders,values) # filter the coefficients
25- V = spline(S) # interpolates -> (100000,) array
26+ from interpolation.splines import UCGrid, CGrid, nodes
2627
27- ```
28+ # we interpolate function
29+ f = lambda x ,y : np.sin(np.sqrt(x** 2 + y** 2 + 0.00001 ))/ np.sqrt(x** 2 + y** 2 + 0.00001 )
2830
29- Unfair timings: (from ` misc/speed_comparison.py ` )
30- ```
31- # interpolate 10^6 points on a 50x50x50 grid.
32- Cubic: 0.11488723754882812
33- Linear: 0.03426337242126465
34- Scipy (linear): 0.6502540111541748
35- ```
31+ # uniform cartesian grid
32+ grid = UCGrid((- 1.0 , 1.0 , 10 ), (- 1.0 , 1.0 , 10 ))
3633
37- More details are available as an example [ notebook] ( https://github.com/EconForge/interpolation.py/blob/master/examples/cubic_splines_python.ipynb )
34+ # get grid points
35+ gp = nodes(grid) # 100x2 matrix
3836
39- Other available features are:
40- - linear extrapolation
41- - computation of derivatives
42- - interpolate many functions at once (multi-splines or vector valued splines)
37+ # compute values on grid points
38+ values = f(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))
4339
44- Experimental
45- - evaluation on the GPU (with numba.cuda)
46- - parallel evaluation (with guvectorize)
40+ from interpolation.splines import eval_linear
41+ # interpolate at one point
42+ point = np.array([0.1 ,0.45 ]) # 1d array
43+ val = eval_linear(grid, values, point) # float
4744
48- In the near future:
49- - JIT classes for all interpolation objects
45+ # interpolate at many points:
46+ points = np.random.random((10000 ,2 ))
47+ eval_linear(grid, values, points) # 10000 vector
5048
49+ # output can be preallocated
50+ out = np.zeros(10000 )
51+ eval_linear(grid, values, points, out) # 10000 vector
5152
5253# # jitted, non-uniform multilinear interpolation
5354
54- There is a simple ` interp ` function with a flexible API which does multinear on uniform or non uniform cartesian grids.
55+ # default calls extrapolate data by using the nearest value inside the grid
56+ # other extrapolation options can be chosen among NEAREST, LINEAR, CONSTANT
57+
58+ from interpolation.splines import extrap_options as xto
59+ points = np.random.random((100 ,2 ))* 3 - 1
60+ eval_linear(grid, values, points, xto.NEAREST ) # 100
61+ eval_linear(grid, values, points, xto.LINEAR ) # 10000 vector
62+ eval_linear(grid, values, points, xto.CONSTANT ) # 10000 vector
63+
64+
65+ # one can also approximate on nonuniform cartesian grids
66+
67+ grid = CGrid(np.linspace(- 1 ,1 ,100 )** 3 , (- 1.0 , 1.0 , 10 ))
68+
69+ points = np.random.random((10000 ,2 ))
70+ eval_linear(grid, values, points) # 10000 vector
71+
72+
73+ # it is also possible to interpolate vector-valued functions in the following way
74+
75+ f = lambda x ,y : np.sin(x** 3 + y** 2 + 0.00001 )/ np.sqrt(x** 2 + y** 2 + 0.00001 )
76+ g = lambda x ,y : np.sin(x** 3 + y** 2 + 0.00001 )/ np.sqrt(x** 2 + y** 2 + 0.00001 )
77+ grid = UCGrid((- 1.0 , 1.0 , 10 ), (- 1.0 , 1.0 , 10 ))
78+ gp = nodes(grid) # 100x2 matrix
79+ mvalues = np.concatenate([
80+ f(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))[:,:,None ],
81+ g(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))[:,:,None ]
82+ ],axis = 2 ) # 10x10x2 array
83+ points = np.random.random((1000 ,2 ))
84+ eval_linear(grid, mvalues, points[:,1 ]) # 2 elements vector
85+ eval_linear(grid, mvalues, points) # 1000x2 matrix
86+ out = np.zeros((1000 ,2 ))
87+ eval_linear(grid, mvalues, points, out) # 1000x2 matrix
88+
89+
90+
91+ # finally, the same syntax can be used to interpolate using cubic splines
92+ # one just needs to prefilter the coefficients first
93+ # the same set of options apply but nonuniform grids are not supported (yet)
94+
95+ f = lambda x ,y : np.sin(x** 3 + y** 2 + 0.00001 )/ np.sqrt(x** 2 + y** 2 + 0.00001 )
96+ grid = UCGrid((- 1.0 , 1.0 , 10 ), (- 1.0 , 1.0 , 10 ))
97+ gp = nodes(grid) # 100x2 matrix
98+ values = f(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))
99+
100+ # filter values
101+ from interpolation.splines import filter_cubic
102+ coeffs = filter_cubic(grid, values) # a 12x12 array
103+
104+ from interpolation.splines import eval_cubic
105+ points = np.random.random((1000 ,2 ))
106+ eval_cubic(grid, coeffs, points[:,1 ]) # 2 elements vector
107+ eval_cubic(grid, coeffs, points) # 1000x2 matrix
108+ out = np.zeros((1000 ,2 ))
109+ eval_cubic(grid, coeffs, points, out) # 1000x2 matrix
110+
111+ ```
112+
113+
114+ ### interp
115+
116+ Simpler interface. Mimmicks default ` scipy.interp ` : mutlilinear interpolation with constant extrapolation.
117+
55118
56119```
57120### 1d grid
@@ -66,10 +129,51 @@ interp(x,y,0.5)
66129# or at many points:
67130u = np.linspace(0,1,1000) # points
68131interp(x,y,u)
132+
133+ ```
134+
135+
136+ ### object interface
137+
138+ This is for compatibility purpose only, until a new jittable model object is found.
139+
140+ ``` python
141+ from interpolation.splines import LinearSpline, CubicSpline
142+ a = np.array([0.0 ,0.0 ,0.0 ]) # lower boundaries
143+ b = np.array([1.0 ,1.0 ,1.0 ]) # upper boundaries
144+ orders = np.array([50 ,50 ,50 ]) # 50 points along each dimension
145+ values = np.random.random(orders) # values at each node of the grid
146+ S = np.random.random((10 ** 6 ,3 )) # coordinates at which to evaluate the splines
147+
148+ # multilinear
149+ lin = LinearSpline(a,b,orders,values)
150+ V = lin(S)
151+ # cubic
152+ spline = CubicSpline(a,b,orders,values) # filter the coefficients
153+ V = spline(S) # interpolates -> (100000,) array
154+
69155```
70156
157+ ### development notes
71158
159+ Old, unfair timings: (from ` misc/speed_comparison.py ` )
72160
161+ ```
162+ # interpolate 10^6 points on a 50x50x50 grid.
163+ Cubic: 0.11488723754882812
164+ Linear: 0.03426337242126465
165+ Scipy (linear): 0.6502540111541748
166+ ```
167+
168+ More details are available as an example [ notebook] ( https://github.com/EconForge/interpolation.py/blob/master/examples/cubic_splines_python.ipynb ) (outdated)
169+
170+ Missing but available soon:
171+ - splines at any order
172+ - derivative
173+
174+ Feasible (some experiments)
175+ - evaluation on the GPU (with numba.cuda)
176+ - parallel evaluation (with guvectorize)
73177
74178
75179
0 commit comments