Multidimensional lookup table using griddedInterpolant

7 visualizaciones (últimos 30 días)
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');

Respuesta aceptada

Nathan Van der Hoek
Nathan Van der Hoek el 3 de Sept. de 2021
Editada: Nathan Van der Hoek el 5 de Sept. de 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.

Más respuestas (1)

Bjorn Gustavsson
Bjorn Gustavsson el 3 de Sept. de 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 comentarios
Nathan Van der Hoek
Nathan Van der Hoek el 3 de Sept. de 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 el 3 de Sept. de 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');

Iniciar sesión para comentar.

Categorías

Más información sobre Interpolation en Help Center y File Exchange.

Productos


Versión

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by