In [1]:
%pylab inline
from mba import *
seed(13)
In [2]:
cmin = [0.0, 0.0]
cmax = [1.0, 1.0]
coo = uniform(0, 1, (7,2))
val = uniform(0, 1, coo.shape[0])
Create $n \times n$ regular grid of coordinates to interpolate onto.
In [3]:
n = 100
s = linspace(0,1,n)
x = array(meshgrid(s,s)).transpose([1,2,0]).copy()
The plot_surface()
function constructs MBA class with the given initial grid size, interpolates the input data over regular surface, and plots the results
In [4]:
def plot_surface(m0):
interp = mba2(cmin, cmax, [m0,m0], coo, val)
error = amax(abs(val - interp(coo))) / amax(abs(val))
v = interp(x)
pcolormesh(s, s, v, cmap='RdBu')
scatter(x=coo[:,0], y=coo[:,1], c=val, cmap='RdBu')
xlim([0,1])
ylim([0,1])
title("$m_0 = {0:}$, error = {1:.3e}".format(m0, error))
colorbar();
The smaller the initial grid size, the smoother the interpolated surface.
In [5]:
figure(figsize=(11,5))
subplot(121); plot_surface(2)
subplot(122); plot_surface(10)
tight_layout()
In [6]:
%%timeit
interp = mba2(cmin, cmax, [3,3], coo, val)
In [7]:
%%timeit interp = mba2(cmin, cmax, [3,3], coo, val)
v = interp(x)
In [8]:
interp = mba2(cmin, cmax, [3,3], coo, val)
print(interp)
By default MBA uses linear approximation as an initial guess. Multilevel B-splines then are used to fit the difference between initial approximation and the actual data. Sometimes it may useful to provide an initial approximation that would better fit the underlying model. Here is a simple example demonstrating this:
In [9]:
def test_initial(x0, y0, init, desc):
interp = mba1([0], [1], [8], x0, y0, init)
x = linspace(0, 1, 100).reshape(100,1)
y = interp(x)
plot(x, y, 'k-')
plot(x, [init(x) for x in x], 'k:')
plot(x0, y0, 'ro')
ylim([0,1])
title(desc)
In [10]:
x = [[0.3], [0.5], [0.7]]
v = [0.45, 0.55, 0.5, ]
figure(figsize=(12, 3))
subplot(131); test_initial(x, v, lambda x: 0.5, 'y = 0.5')
subplot(132); test_initial(x, v, lambda x: x[0], 'y = x')
subplot(133); test_initial(x, v, lambda x: 1-x[0], 'y = 1-x')
tight_layout()