Multidimensional lookup table using griddedInterpolant

5 Ansichten (letzte 30 Tage)
Hi, I have a function that computes an output value and I want to create a lookup table with interpolation (and I've found griddedInterpolant can do that) of these computed values, varying the parameters passed to the function. I'd like to be able to specify a number of vectors that contain varying parameters, maybe just 1 vector of varying parameters or maybe many - I want to able to change it fairly easily. In the example below I am varying 3 parameters, so the resultant look up table will be a 3D array. I am using allcomb from the file exchange to generate all the different combinations of input parameters, looping over them and performing a calculation with the values from each row. I want the griddedInterpolant to be able to give me the result corresponding to the configuration but for testing I am just storing the current iteration number 'ndx' in the array. I would like to be able to extract the result from any configuration by doing u_LUT(x,y,z).
From the code below I WANT:
u_LUT(-2,-1,-4) returns 1
u_LUT(-2,-1,-3.5) returns 2
u_LUT(-2,-1,-3) returns 3
...
u_LUT(-2,-1,4) returns 17
u_LUT(-2,-0.75,-4) returns 18
u_LUT(-2,-0.75,-3.5) returns 19
and so on, such that the result produced by the interpolant is for the correct configuration passed in as u_LUT(x,y,z).
But I cannot set up the griddedInterpolant to produce this behaviour. I feel I have to manipulate 'u' in some way to get it from the matlab linear indexing arrangement into the arrangement I need for the griddedInterpolant. Thanks in advance for any help.
clear
clc
% vectors of input paramters
% a calculation will be performed with every combination of these
x = -2:0.1:2;
y = -1:0.25:1;
z = -4:0.5:4;
inputs = {x, y, z};
% generate all combinations of inputs
input_configurations = allcomb(inputs{:});
num_configurations = size(input_configurations,1);
num_inputs = length(inputs);
sizes_of_inputs = ones(1, num_inputs);
for index = 1:num_inputs
sizes_of_inputs(index) = size(inputs{index},2);
end
% u stores the result of the calculation using x, y & z
u = ones(sizes_of_inputs);
for ndx = 1:num_configurations
% calculation performed here with x,y,z from
% input_configurations(ndx,:) - result stored in u
% u(ndx) = calculationCall(x,y,z)
u(ndx) = ndx;
end
u_LUT = griddedInterpolant(inputs, u, 'spline');

Akzeptierte Antwort

Nathan Van der Hoek
Nathan Van der Hoek am 3 Sep. 2021
Bearbeitet: Nathan Van der Hoek am 5 Sep. 2021
Edit: I discovered allcomb has the option to vary the parameters beginning with the left-most one rather than the right-most one if you pass it the option 'matlab'. This means when the result array ('u' above) is indexed via linear indexing, the results are going into the correct place.
I managed to reshape the data I originally had with:
u_rearranged = permute(reshape(u, flip(sizes_of_inputs)), num_inputs:-1:1);
But this is no longer necessary for me.

Weitere Antworten (1)

Bjorn Gustavsson
Bjorn Gustavsson am 3 Sep. 2021
If you calculate all the combinations of points you dont need to go over the allcomb way, you could just as well run ndgrid at once. Then your code-snippet would become something like:
% vectors of input paramters
% a calculation will be performed with every combination of these
x = -2:0.1:2;
y = -1:0.25:1;
z = -4:0.5:4;
[X,Y,Z] = ndgrid(x,y,z);
% u stores the result of the calculation using x, y & z
u = ones(size(X));
for i1 = sizer(X,1):-1:1 % looping from the end makes it possible to dodge pre-allocation
for i2 = size(X,2):-1:1 % which is sometimes convenient, but not always possible
for i3 = size(X,3):-1:1
% calculation performed here with x,y,z from
% X(i1,i2,i3), Y(i1,i2,i3), Z(i1,i2,i3) - result stored in u
% u(i1,i2,i3) = calculationCall(x,y,z)
u(i1,i2,i3) = ndx;
end
end
end
u_LUT = griddedInterpolant(X,Y,Z, u, 'spline');
HTH
  2 Kommentare
Nathan Van der Hoek
Nathan Van der Hoek am 3 Sep. 2021
I want my code to work for an arbitrary number of inputs. The way you've written it, if I want 3 more vectors to the ndgrid, I would need to create 3 more nested for loops. I am trying to avoid that.
Bjorn Gustavsson
Bjorn Gustavsson am 3 Sep. 2021
Then use linear indexing:
for i1 = size(X(:),1):-1:1
U(i1) = sin(X(i1)+Y(i1)+Z(i1));
end
u_LUT = griddedInterpolant(X,Y,Z, reshape(U,size(X)), 'spline');

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Interpolation finden Sie in Help Center und File Exchange

Produkte


Version

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by