Multidimensional data storage and interpolation

Viewed 69

I have a function (so to speak, i actually have data with this characteristic) with one variable x and several parameters a, b and c, so y = f(x, a, b, c). Now i want to interpolate within families of parameters (for example for variations of a).

I'm currently doing this for data with one parameter (here, y is the data matrix)

% generate variable and data
x = linspace(0, 1, 100);
a = [0, 1]; % parameter
for i = 1:length(a)
    y(:, i) = x.^2 + a(i);
end
% interpolate:
yi = interp1(a, y.', 0.5);

This works fine, but how do i expand this to more dimensions?

My current data format is like this: Each column of my data matrix represents one specific set of parameters, so for example:

0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3

where the first column denotes a = 0, b = 0, the second a = 1, b = 0, the third a = 0, b = 1 and the last a = 1, b = 1 (values are just for clarification, this is not on purpose binary. Also, the data columns are obviously not the same).

This data format is just the consequence of my data aquisition scheme, but i'm happy to change this into something more useful. Whatever works.

2 Answers

Works well for me:

% generate variable and data
x = linspace(0, 1, 100);
a = [0, 1, 2]; % parameter
b = [3, 4, 5]; % parameter
c = [6, 7, 8]; % parameter

% Create grid
[X,A,B,C]=ndgrid(x,a,b,c);

% define function
foo = @(x,p1,p2,p3) p1.*x.^2 + p2.*x + p3;

% evaluate function
Y = foo(X,A,B,C);

% interpolate:
yi = interpn(X,A,B,C,Y,x,1,4,6);

@zlon's answer works fine for the interpolation part, here i want to show how to convert the data from the format i provided to the needed format for the interpolation.

The two-dimensional matrix must be transformed into a N-dimensional one. Since the columns are not necessarily in order, we need to find the right ones. This is what i did:

First, we need to know the parameter set of each column:

a = [ 2, 2, 1, 0, 0, 1 ];
b = [ 1, 0, 0, 1, 0, 1 ];

These vectors length match the number of columns in the data matrix. The first column for example now contains the data for a = 2 and b = 1.

Now we can generate the new table:

A = -Inf;
i = 1;
while true
    A = min(a(a > A)); % find next a
    if isempty(A)
        break
    end
    idxa = find(a == A); % store possible indices
    B = -Inf;
    j = 1;
    while true
        B = min(b(b > B))); % find next b
        if isempty(B)
            break
        end
        idxb = find(b == B); % store possible indices
        % combine both indices
        idx = intersect(idxa, idxb);
        % save column in new data table
        data(:, i, j) = olddata(:, idx);
        % advance
        j = j + 1;
    end
    i = i + 1;
end
Related