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 ]) # 10 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
36+
37+ # compute values on grid points
38+ values = f(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))
39+
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
44+
45+ # interpolate at many points:
46+ points = np.random.random((10000 ,2 ))
47+ eval_linear(grid, values, points) # 10000 vector
48+
49+ # output can be preallocated
50+ out = np.zeros(10000 )
51+ eval_linear(grid, values, points, out) # 10000 vector
52+
53+
54+ # default calls extrapolate data by using the nearest value inside the grid
55+ # other extrapolation options can be chosen among NEAREST, LINEAR, CONSTANT
56+
57+ from interpolation.splines import extrap_options as xto
58+ points = np.random.random((100 ,2 ))* 3 - 1
59+ eval_linear(grid, values, points, xto.NEAREST ) # 100
60+ eval_linear(grid, values, points, xto.LINEAR ) # 10000 vector
61+ eval_linear(grid, values, points, xto.CONSTANT ) # 10000 vector
62+
63+
64+ # one can also approximate on nonuniform cartesian grids
65+
66+ grid = CGrid(np.linspace(- 1 ,1 ,100 )** 3 , (- 1.0 , 1.0 , 10 ))
67+
68+ points = np.random.random((10000 ,2 ))
69+ eval_linear(grid, values, points) # 10000 vector
70+
71+
72+ # it is also possible to interpolate vector-valued functions in the following way
73+
74+ f = lambda x ,y : np.sin(x** 3 + y** 2 + 0.00001 )/ np.sqrt(x** 2 + y** 2 + 0.00001 )
75+ g = lambda x ,y : np.sin(x** 3 + y** 2 + 0.00001 )/ np.sqrt(x** 2 + y** 2 + 0.00001 )
76+ grid = UCGrid((- 1.0 , 1.0 , 10 ), (- 1.0 , 1.0 , 10 ))
77+ gp = nodes(grid) # 100x2 matrix
78+ mvalues = np.concatenate([
79+ f(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))[:,:,None ],
80+ g(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))[:,:,None ]
81+ ],axis = 2 ) # 10x10x2 array
82+ points = np.random.random((1000 ,2 ))
83+ eval_linear(grid, mvalues, points[:,1 ]) # 2 elements vector
84+ eval_linear(grid, mvalues, points) # 1000x2 matrix
85+ out = np.zeros((1000 ,2 ))
86+ eval_linear(grid, mvalues, points, out) # 1000x2 matrix
3887
39- Other available features are:
40- - linear extrapolation
41- - computation of derivatives
42- - interpolate many functions at once (multi-splines or vector valued splines)
4388
44- Experimental
45- - evaluation on the GPU (with numba.cuda)
46- - parallel evaluation (with guvectorize)
4789
48- In the near future:
49- - JIT classes for all interpolation objects
90+ # finally, the same syntax can be used to interpolate using cubic splines
91+ # one just needs to prefilter the coefficients first
92+ # the same set of options apply but nonuniform grids are not supported (yet)
5093
94+ f = lambda x ,y : np.sin(x** 3 + y** 2 + 0.00001 )/ np.sqrt(x** 2 + y** 2 + 0.00001 )
95+ grid = UCGrid((- 1.0 , 1.0 , 10 ), (- 1.0 , 1.0 , 10 ))
96+ gp = nodes(grid) # 100x2 matrix
97+ values = f(gp[:,0 ], gp[:,1 ]).reshape((10 ,10 ))
5198
52- ## jitted, non-uniform multilinear interpolation
99+ # filter values
100+ from interpolation.splines import filter_cubic
101+ coeffs = filter_cubic(grid, values) # a 12x12 array
102+
103+ from interpolation.splines import eval_cubic
104+ points = np.random.random((1000 ,2 ))
105+ eval_cubic(grid, coeffs, points[:,1 ]) # 2 elements vector
106+ eval_cubic(grid, coeffs, points) # 1000x2 matrix
107+ out = np.zeros((1000 ,2 ))
108+ eval_cubic(grid, coeffs, points, out) # 1000x2 matrix
109+
110+ ```
111+
112+
113+ ### interp
114+
115+ Simpler interface. Mimmicks default ` scipy.interp ` : mutlilinear interpolation with constant extrapolation.
53116
54- There is a simple ` interp ` function with a flexible API which does multinear on uniform or non uniform cartesian grids.
55117
56118```
57119### 1d grid
@@ -66,10 +128,51 @@ interp(x,y,0.5)
66128# or at many points:
67129u = np.linspace(0,1,1000) # points
68130interp(x,y,u)
131+
132+ ```
133+
134+
135+ ### object interface
136+
137+ This is for compatibility purpose only, until a new jittable model object is found.
138+
139+ ``` python
140+ from interpolation.splines import LinearSpline, CubicSpline
141+ a = np.array([0.0 ,0.0 ,0.0 ]) # lower boundaries
142+ b = np.array([1.0 ,1.0 ,1.0 ]) # upper boundaries
143+ orders = np.array([50 ,50 ,50 ]) # 10 points along each dimension
144+ values = np.random.random(orders) # values at each node of the grid
145+ S = np.random.random((10 ^ 6 ,3 )) # coordinates at which to evaluate the splines
146+
147+ # multilinear
148+ lin = LinearSpline(a,b,orders,values)
149+ V = lin(S)
150+ # cubic
151+ spline = CubicSpline(a,b,orders,values) # filter the coefficients
152+ V = spline(S) # interpolates -> (100000,) array
153+
69154```
70155
156+ ### development notes
71157
158+ Old, unfair timings: (from ` misc/speed_comparison.py ` )
72159
160+ ```
161+ # interpolate 10^6 points on a 50x50x50 grid.
162+ Cubic: 0.11488723754882812
163+ Linear: 0.03426337242126465
164+ Scipy (linear): 0.6502540111541748
165+ ```
166+
167+ More details are available as an example [ notebook] ( https://github.com/EconForge/interpolation.py/blob/master/examples/cubic_splines_python.ipynb ) (outdated)
168+
169+ Missing but available soon:
170+ - splines at any order
171+ - derivative
172+
173+ Feasible (some experiments)
174+ - evaluation on the GPU (with numba.cuda)
175+ - parallel evaluation (with guvectorize)
73176
74177
75178
0 commit comments