<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Using MBA
cmin and cmax are coordinates of the bottom-left and the top-right corners of the bounding box containing scattered data. coo and val are arrays containing coordinates and values of the data points.
Step1:  Create $n \times n$ regular grid of coordinates to interpolate onto.
Step2:  The plot_surface() function constructs MBA class with the given initial grid size, interpolates the input data over regular surface, and plots the results
Step3:  The smaller the initial grid size, the smoother the interpolated surface.
Step4:  Report some timings and statistics about the constructed hierarchy
Step5:  Specifing the initial approximation
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
<ASSISTANT_TASK:>
Python Code:
cmin = [0.0, 0.0]
cmax = [1.0, 1.0]
coo  = uniform(0, 1, (7,2))
val  = uniform(0, 1, coo.shape[0])
Explanation: Using MBA
cmin and cmax are coordinates of the bottom-left and the top-right corners of the bounding box containing scattered data. coo and val are arrays containing coordinates and values of the data points.
End of explanation
n = 100
s = linspace(0,1,n)
x = array(meshgrid(s,s)).transpose([1,2,0]).copy()
Explanation: Create $n \times n$ regular grid of coordinates to interpolate onto.
End of explanation
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();
Explanation: The plot_surface() function constructs MBA class with the given initial grid size, interpolates the input data over regular surface, and plots the results
End of explanation
figure(figsize=(11,5))
subplot(121); plot_surface(2)
subplot(122); plot_surface(10)
tight_layout()
Explanation: The smaller the initial grid size, the smoother the interpolated surface.
End of explanation
%%timeit
interp = mba2(cmin, cmax, [3,3], coo, val)
%%timeit interp = mba2(cmin, cmax, [3,3], coo, val)
v = interp(x)
interp = mba2(cmin, cmax, [3,3], coo, val)
print(interp)
Explanation: Report some timings and statistics about the constructed hierarchy:
End of explanation
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)
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()
Explanation: Specifing the initial approximation
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:
End of explanation
<END_TASK>