Sparse Grid Interpolation Toolbox Previous pageNext page

Improving Performance

The aim of this section is to provide an overview on how to optimize the performance of the Sparse Grid Interpolation Toolbox.

Contents

Vectorizing the objective function

Vectorizing the objective function is most beneficial if the function evaluations are very cheap, in the order of less than 1/100 s. In this case, providing a vectorized function can improve the performance of the spvals function. Consider the following function

and the following two m-files implementing it:

type fun.m
function y = fun(x1, x2)
y = x1 * x2;
y = y^2;
type fun_vec.m
function y = fun_vec(x1, x2)
y = x1 .* x2;    % Use '.' before any '^', '*' or '/' to enable
y = y.^2;        % vectorized evaluation of expressions

The first m-file allows for evaluation at a single real-valued point only, the second one permits vectorized evaluation. Since in case of cheap functions, the function calls in Matlab represent a significant overhead, the function evaluation part of the spvals algorithm is much slower if the non-vectorized form is used. This is demonstrated by the following code.

tic, z1 = spvals('fun',2); toc;
tic, z2 = spvals('fun_vec',2,[],spset('Vectorized','on')); toc;
z1.fevalTime
z2.fevalTime
Elapsed time is 0.112452 seconds.
Elapsed time is 0.069006 seconds.
ans =
    0.1021
ans =
    0.0480

Reusing previous results

An important feature of the toolbox is that you do not have to discard previously computed results. A "best practice" is, therefore, to embed the interpolant construction in a loop. Proceeding in this way has two advantages: First, it gives the user a maximum of control in monitoring the decay of the estimated interpolation error. Second, it makes it possible to start with a low number of required points, and to increase this number slowly if the targeted accuracy is not yet achieved. There are several examples on how to implement such a loop in the provided demos. See, for instance, spadaptanim.m or spcompare.m in the examples directory.

A small example on implementing dimension-adaptive interpolant construction in a loop is provided below.

np = 2;
z  = [];
options = spset('Vectorized', 'on', 'DimensionAdaptive', 'on', ...
  'RelTol', inf);
while np < 4000
  options = spset(options, 'PrevResults', z, 'MinPoints', np, 'MaxPoints', np);
  z = spvals('fun_vec',2,[],options);
  np = z.nPoints;
  disp(['np = ' num2str(np) ', e_rel = ', num2str(z.estRelError)]);
  np = np * 2;
end
np = 5, e_rel = 0.75
np = 13, e_rel = 0.5625
np = 29, e_rel = 0.046875
np = 73, e_rel = 0.011719
np = 177, e_rel = 0.0029297
np = 417, e_rel = 0.00073242
np = 897, e_rel = 6.1035e-05
np = 1921, e_rel = 4.5776e-05
np = 4097, e_rel = 3.8147e-06

Purging interpolant data

Since version v3.2 of the toolbox, a new function called sppurge is available. This function serves to "purge" or "clean up" the interpolant data from subgrids that do not contribute significantly to the result. This is done by introducing a drop tolerance that is applied to the hierarchical surpluses. Subgrids where the absolute value of all hierarchical surpluses fall below this drop tolerance are marked and neglected during the interpolation process. By default, very conservative purging parameters are used, guaranteeing that the accuracy of the interpolation will not be affected up to about the 12th significant digit. However, if the accuracy requirements are lower, the user may use higher drop tolerances, and thus, trade improved interpolation speed against lower accuracy. This is illustrated by the following example.

We assume that an interpolant was computed for the function fun_vec by the code above with 4097 points, using piecewise multilinear basis functions. The following code generates a plot that shows the time required to compute 1000 randomly sampled points for different drop tolerances. The maximum absolute error is shown for comparison. This example only uses absolute drop tolerances (the relative drop tolerance is set to zero).

% Define drop tolerances
dropTols = [1e-5, 1e-4, 1e-3];

% Generate 1000 random points
rand('state',0);
x = rand(1000,1); y = rand(1000,1);

% Compute exact function values
f_exact = fun_vec(x,y);

e = zeros(3,1); t = zeros(3,1);
for k = 1:3
  % Purge interpolant with drop tolerance
  z = sppurge(z,spset('DropTol', [dropTols(k), 0]));
  % Interpolate and measure time
  tic, ip = spinterp(z, x, y); t(k) = toc;
  % Compute maximum error
  e(k) = max(abs(f_exact - ip));
end

% Plot results
subplot(1,2,1);
bar(t, 'b');
set(gca,'XTickLabel', {'1e-5','1e-4','1e-3'})
xlabel('Abs. drop tolerance');
ylabel('Computing time [s]');
subplot(1,2,2);
bar(log10(e), 'r');
set(gca,'XTickLabel', {'1e-5','1e-4','1e-3'})
set(gca,'YDir','reverse');
set(gca,'YLim', [-6 -2]);
set(gca,'YTick',[-5 -4 -3]);
set(gca,'YTickLabel', {'1e-5','1e-4','1e-3'})
xlabel('Abs. drop tolerance');
ylabel('Max. absolute error');

For another example using the default relative drop tolerance, see sppurge.

Vectorized interpolant evaluation

The spinterp function is designed for vectorized evaluation. Since the sparse grid algorithm involves more computational overhead than other, simpler interpolation methods, and due to the fact that Matlab is relatively slow if many function calls are performed (since it is an interpreted language), it is recommended to evaluate as many interpolation points at a time as possible. The following code illustrates non-vectorized vs. vectorized evaluation at 1000 points for the interpolant from above.

% Non-vectorized interpolation
tic
for k = 1:1000
  ip = spinterp(z,x(k),y(k));
end
toc

% Vectorized interpolation
tic, ip = spinterp(z,x,y); toc
Elapsed time is 2.526127 seconds.
Elapsed time is 0.045744 seconds.