Multidimensional lookup table using griddedInterpolant

조회 수: 10 (최근 30일)
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');

채택된 답변

Nathan Van der Hoek
Nathan Van der Hoek 2021년 9월 3일
편집: Nathan Van der Hoek 2021년 9월 5일
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.

추가 답변 (1개)

Bjorn Gustavsson
Bjorn Gustavsson 2021년 9월 3일
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
Nathan Van der Hoek
Nathan Van der Hoek 2021년 9월 3일
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 2021년 9월 3일
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');

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Resizing and Reshaping Matrices에 대해 자세히 알아보기

제품


릴리스

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by