Reverse 2D-lookup Table

I am having a lot of difficulty implementing this typ of controller in simulink.
To put it simply have a 2d-Lookup table a basically want to reverse engineer it. The 2d-lookup table takes in two input A and B and interpolates the corresponding output C in a large 79x101 matrix. I wish to define the output variable C for a fixed input variable A and find the corresponding variable B.
_____________
A--->| |
|2d-Looukup |--->C
B--->|___________|
____________
C--->| Reverse |
| lookup |--->B
A--->|___________|
What I have been attempting is to focus on first is the input A. So lets say for example that I have the following matrix.
0.4 0.5 0.6 0.7 (B)
____________________
17.9|67 89 95 108
(A) 18.0|74 92 110 123
18.1|80 97 115 127
18.2|84 106 119 135
(C)
I have an input of 18.046 for the input A. Now matlab will interpolate between 18.0
and 18.1 to give me the following output.
0.4 0.5 0.6 0.7 (B)
___________________
(A)8.046|76 94 112 125
(C)
So with the matrix output as shown below I define my desired output variable, e.g. C = 105. I then pass this variable C into a lookup table and matlab will interpolate the corresponding input variable B.
0.4 0.5 0.6 0.7
  __________________
(C) 105--->|76 94 111 125| ---> 0.57 (B)
Could anyone help me in acheieving this problem as I have been stuck on it for quite some time now. Much appreciated
Owen

5 Comments

Is your function single-valued? Does each Z value have one unique (X,Y) location? For example, Z=rand(1000,1000) would have lots of locations (perhaps a million or more) that could be interpolated to have a value of 0.5.
Owen
Owen on 7 Aug 2011
Thank you image analyst for your reply.
No the function is not single valued (not unique). The 2d-lookup table takes in two values and each must be interpolated to their nearest value. If I were just to use the output value C to try and find the corresponding A and B values Simulink would return me a large number of A and B combinations that correspond to that C value.
That is why I have been trying to separate this problem into two steps. First step is that I know one of the input values A (e.g. 14.45), so I am trying to ask simulink to interpolate between 14.4 and 14.5. The problem with this request is that I require matlab to output the entire interpolated row i.e. for every B value.
I not sure if it is possible for matlab to output a multiple elements (i.e a 1x101 matrix)in a single interpolation. I was thinking of trying some sort of loop to repeat this interpolation for every single column and then construct a 1x101 matrix using these outputs.
Appreciate the response.
Dear, I had the same doubt, excellent, thank you very much,very gratefull..
Hello
i had the same issue i wanted to inverse a 2D lookup table, i tried the formula in the previous comments but it gives NAN values so i creted my own formula, it's so simple based on one interpolation :
here is my script
clc
nbrC1 = 3 ; %nombre d'elelements desiré dans le vecteur C1
A=[1 2 ];
B=[1 2 ];
C=[2 3 ; 3 4 ];
%objectif passer de : entrée sont A et B à entrées A et C
%calcul de la matrice B1 et des deux lignes A1 et C1
%A1=A inchangé
%etape 1 : les elements de la ligne C1
minC=min(min(C));
maxC=max(max(C));
precision=(maxC-minC)/(nbrC1-1) ;
C1=minC:precision:maxC ;
nA= size(A) ;
nA= nA(2) ;
nC1= size(C1) ;
nC1= nC1(2) ;
% etape 2 les valeurs de B1 ( matrice )
B1=zeros(nA,nC1);
for i= 1:nA
tmpC=C(i,:);
for j = 1:nC1
B1(i,:)=interp1( tmpC,B,C1, 'spline', 'extrap');
end
end
% the result
%B1
%C1
%A1 = A
%Marouan AKHABBIL
This script works well, but not for me: A has a size of 8, B has a size of 32.
I set nbrC1 = 8
But it doesnt woork for me: C1 has weird values
How can i fix this?

Sign in to comment.

 Accepted Answer

For a given value of A1 and C1, you should be able to find the corresponding value B1. Do a two-loop iteration on different values of A and C, you should be able to reverse engineer the lookup table.
A=[17.9 18.0 18.1 18.2]';
B=[0.4 0.5 0.6 0.7];
C=[67 89 95 108
74 92 110 123
80 97 115 127
84 106 119 135];
A1=18.046;
%Z=interp2(A,B,C,A1,B);
Z=interp2(A,B,C',A1,B);
C1=105;
B1=interp1(Z,B,C1);

21 Comments

Owen
Owen on 7 Aug 2011
That looks like a nice way of finding the input value B1, however I am having difficulties implementing.
Let's stick with the code that you have used above for now.
When I input that A, B, C and A1 into matlab and attempt to do interp2 function you I get an incorrect values.
The values I get for Z are:
Z = [91.76 100.28 105.28 111.98]
What I would expect to get when would be something like(off top of my head):
[76.8 94.5 112.4 121.9]
There is something not working as intended in this interp2 function I believe. A similar issue occurs when I try to use this with my code so I am left questioning the interp2 function. I believe that interp2 function uses linear interpolation as default which is what I desire so that is not an issue.
Will go at it again in the morning as it is late now but thank you very much for your effort so far, feel like making some sort of progress finally.
Good point! It should be Z=interp2(A,B,C',A1,B). It is the definition of the column and row for a 2D lookup table.
Owen
Owen on 8 Aug 2011
That is great Fangiun Jiang, does exactly as wanted.
If I could trouble you for one more bit of assistance.
I am trying to use an embedded Matlab function to place this into my simulink model however embedded functions don't support 'interp2' function.
Should I be using a different user defined function to place this code into matlab?
Dear For me it is the proposed seamless. Copy the code as it is in a m-file, execute it, and I think the result is acceptable, as this goes along with the interpolation method used. So I use this solution ... Thank you friends..
A=[17.9 18.0 18.1 18.2]';
B=[0.4 0.5 0.6 0.7];
C=[67 89 95 108;...
74 92 110 123;...
80 97 115 127;...
84 106 119 135];
A1=18.1;%18.046;
%Z=interp2(A,B,C,A1,B);
Z=interp2(A,B,C',A1,B,'linear')
C1=105;
B1=interp1(Z,B,C1,'linear')
%ANSWERS WITH DIFFERENT METHODS:
% %0.5425:cubic, 0.5409:splines,0.5444:linear,0.5:nearest
But, I have the following problem: My Z is messy, it is not strictly increasing as called matlab, to apply it interp1. How I can interpolate Z ordered, without ceasing to belong each to its corresponding Z value in B?. If I messed Z command B or vice versa ... will there any solution? I would appreciate any comments ... GREETINGS
Jan
Jan on 25 Jul 2013
@Pablo: Is this a question or a comment? If it is a new question, please open a new thread.
Would this be possible for a 3-D lookup table?
Hi,
how could I implement this in Simulink? The output of the first 2D-lookup-table must be the table data for the second 1D-lookup-table.
Appreciate the response.
This script works fine if A and B have the same size.
my case, i have a 32 * 8 Lookup and i get some error on z=interp2.
How can i fix this?
@Michael Goebel "This script works fine if A and B have the same size."
Wrong, A B can have differet size. However size(C) must be length(A) x length(B).
A has 4 elements
B has 4 elements
C has 16 elements.
Maybe i cant count cause its friday
rng('default')
A = sort(rand(32,1));
B = sort(rand(8,1));
C = rand(8,32);
A1 = 0.2;
Z = interp2(A,B,C,A1,B)
Z = 8×1
0.4310 0.5414 0.0587 0.1300 0.4318 0.7832 0.7668 0.2369
C1 = 0.7;
B1 = interp1(Z,B,C1)
B1 = 0.5931
Bruno Luong
Bruno Luong on 2 Sep 2022
Edited: Bruno Luong on 2 Sep 2022
You count right, A has 4, B has 4 and C has 4x4 = 16 elements.
What is the problem?
Thats a good question.
Here is my raw-Data:
A = [0.5:0.5:16]';
B = [-20,-10,0,25,40,60,80,100]';
C = reshape([0.142,0.234,0.325,0.417,0.508,0.599,0.69,0.781,0.872,0.963,1.054,1.145,1.235,1.326,1.417,1.508,1.598,1.689,1.779,1.87,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,0.173,0.265,0.356,0.447,0.539,0.63,0.72,0.811,0.902,0.993,1.083,1.174,1.265,1.355,1.445,1.536,1.626,1.716,1.806,1.896,1.987,2.08,2.173,2.265,2.358,2.451,2.543,2.636,2.731,2.827,2.924,3.021,0.301,0.393,0.483,0.574,0.664,0.753,0.843,0.932,1.022,1.114,1.206,1.299,1.395,1.491,1.587,1.683,1.781,1.879,1.977,2.076,2.176,2.275,2.375,2.474,2.573,2.673,2.773,2.873,2.973,3.072,3.172,3.271,0.318,0.608,0.694,0.78,0.865,0.951,1.038,1.129,1.221,1.314,1.408,1.503,1.597,1.692,1.788,1.883,1.978,2.072,2.167,2.262,2.357,2.451,2.545,2.638,2.732,2.826,2.919,3.011,3.104,3.196,3.288,3.379,0.313,0.612,0.898,1.172,1.339,1.393,1.452,1.515,1.58,1.646,1.712,1.78,1.848,1.916,1.985,2.054,2.123,2.193,2.263,2.334,2.406,2.477,2.55,2.623,2.696,2.77,2.844,2.918,2.992,3.067,3.142,3.217,0.31,0.599,0.871,1.129,1.376,1.513,1.554,1.6,1.649,1.7,1.753,1.807,1.863,1.92,1.978,2.038,2.1,2.163,2.227,2.292,2.359,2.426,2.495,2.564,2.634,2.704,2.776,2.848,2.92,2.993,3.067,3.142,0.3,0.564,0.808,1.043,1.278,1.516,1.631,1.658,1.689,1.723,1.761,1.803,1.849,1.899,1.952,2.007,2.064,2.124,2.186,2.249,2.314,2.38,2.448,2.517,2.587,2.658,2.73,2.803,2.877,2.951,3.026,3.102,0.29,0.538,0.773,1.011,1.254,1.501,1.67,1.689,1.713,1.742,1.777,1.817,1.861,1.908,1.959,2.013,2.069,2.128,2.188,2.251,2.316,2.382,2.45,2.519,2.588,2.659,2.731,2.804,2.879,2.954,3.029,3.105],32,8)';
I want to find the fitting Value of A with a a defined value of B and C with linear interpolation and "nearest", but i often get NaN
I want to find the fitting Value of A with a a defined value of B and C with linear interpolation and "nearest", but i often get NaN
Then you should give the code for such an example.
Edit: It works now as a . file with this code:
AA = [-20,-10,0,25,40,60,80,100]'; % Temperatur
BB = [0.5:0.5:16]; % Fluss
CC = reshape([0.142,0.234,0.325,0.417,0.508,0.599,0.69,0.781,0.872,0.963,1.054,1.145,1.235,1.326,1.417,1.508,1.598,1.689,1.779,1.87,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,0.173,0.265,0.356,0.447,0.539,0.63,0.72,0.811,0.902,0.993,1.083,1.174,1.265,1.355,1.445,1.536,1.626,1.716,1.806,1.896,1.987,2.08,2.173,2.265,2.358,2.451,2.543,2.636,2.731,2.827,2.924,3.021,0.301,0.393,0.483,0.574,0.664,0.753,0.843,0.932,1.022,1.114,1.206,1.299,1.395,1.491,1.587,1.683,1.781,1.879,1.977,2.076,2.176,2.275,2.375,2.474,2.573,2.673,2.773,2.873,2.973,3.072,3.172,3.271,0.318,0.608,0.694,0.78,0.865,0.951,1.038,1.129,1.221,1.314,1.408,1.503,1.597,1.692,1.788,1.883,1.978,2.072,2.167,2.262,2.357,2.451,2.545,2.638,2.732,2.826,2.919,3.011,3.104,3.196,3.288,3.379,0.313,0.612,0.898,1.172,1.339,1.393,1.452,1.515,1.58,1.646,1.712,1.78,1.848,1.916,1.985,2.054,2.123,2.193,2.263,2.334,2.406,2.477,2.55,2.623,2.696,2.77,2.844,2.918,2.992,3.067,3.142,3.217,0.31,0.599,0.871,1.129,1.376,1.513,1.554,1.6,1.649,1.7,1.753,1.807,1.863,1.92,1.978,2.038,2.1,2.163,2.227,2.292,2.359,2.426,2.495,2.564,2.634,2.704,2.776,2.848,2.92,2.993,3.067,3.142,0.3,0.564,0.808,1.043,1.278,1.516,1.631,1.658,1.689,1.723,1.761,1.803,1.849,1.899,1.952,2.007,2.064,2.124,2.186,2.249,2.314,2.38,2.448,2.517,2.587,2.658,2.73,2.803,2.877,2.951,3.026,3.102,0.29,0.538,0.773,1.011,1.254,1.501,1.67,1.689,1.713,1.742,1.777,1.817,1.861,1.908,1.959,2.013,2.069,2.128,2.188,2.251,2.316,2.382,2.45,2.519,2.588,2.659,2.731,2.804,2.879,2.954,3.029,3.105],32,8)';
AA1 = 25;
ZZ = interp2(AA,BB,CC',AA1,BB,'linear') %Suche A1 in A = Suche
CC1 = 1.314;
BB1 = interp1(ZZ,BB,CC1,'linear')
But: When i try this code in Simulink as a matlab function, i get errors
Code of Simulink function:
function Q_Pumpe_von_Rotor = fcn(RotorRequest,Temp)
AA = [-20,-10,0,25,40,60,80,100]';
BB = [0.5:0.5:16];
CC = reshape([0.142,0.234,0.325,0.417,0.508,0.599,0.69,0.781,0.872,0.963,1.054,1.145,1.235,1.326,1.417,1.508,1.598,1.689,1.779,1.87,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,1.96,0.173,0.265,0.356,0.447,0.539,0.63,0.72,0.811,0.902,0.993,1.083,1.174,1.265,1.355,1.445,1.536,1.626,1.716,1.806,1.896,1.987,2.08,2.173,2.265,2.358,2.451,2.543,2.636,2.731,2.827,2.924,3.021,0.301,0.393,0.483,0.574,0.664,0.753,0.843,0.932,1.022,1.114,1.206,1.299,1.395,1.491,1.587,1.683,1.781,1.879,1.977,2.076,2.176,2.275,2.375,2.474,2.573,2.673,2.773,2.873,2.973,3.072,3.172,3.271,0.318,0.608,0.694,0.78,0.865,0.951,1.038,1.129,1.221,1.314,1.408,1.503,1.597,1.692,1.788,1.883,1.978,2.072,2.167,2.262,2.357,2.451,2.545,2.638,2.732,2.826,2.919,3.011,3.104,3.196,3.288,3.379,0.313,0.612,0.898,1.172,1.339,1.393,1.452,1.515,1.58,1.646,1.712,1.78,1.848,1.916,1.985,2.054,2.123,2.193,2.263,2.334,2.406,2.477,2.55,2.623,2.696,2.77,2.844,2.918,2.992,3.067,3.142,3.217,0.31,0.599,0.871,1.129,1.376,1.513,1.554,1.6,1.649,1.7,1.753,1.807,1.863,1.92,1.978,2.038,2.1,2.163,2.227,2.292,2.359,2.426,2.495,2.564,2.634,2.704,2.776,2.848,2.92,2.993,3.067,3.142,0.3,0.564,0.808,1.043,1.278,1.516,1.631,1.658,1.689,1.723,1.761,1.803,1.849,1.899,1.952,2.007,2.064,2.124,2.186,2.249,2.314,2.38,2.448,2.517,2.587,2.658,2.73,2.803,2.877,2.951,3.026,3.102,0.29,0.538,0.773,1.011,1.254,1.501,1.67,1.689,1.713,1.742,1.777,1.817,1.861,1.908,1.959,2.013,2.069,2.128,2.188,2.251,2.316,2.382,2.45,2.519,2.588,2.659,2.731,2.804,2.879,2.954,3.029,3.105],32,8)';
%% AA1 = 25;
% ZZ = interp2(AA,BB,CC',AA1,BB,'linear'); %Suche A1 in A = Suche
ZZ = interp2(AA,BB,CC',Temp,BB,'linear'); %Suche A1 in A = Suche
CC1 = 1.314;
% BB1 = interp1(ZZ,BB,CC1,'linear');
BB1 = interp1(ZZ,BB,RotorRequest,'linear');
Q_Pumpe_von_Rotor = BB1
Errors:
Simulink does not have enough information to determine output sizes for this block. If you think the errors below are inaccurate, try specifying types for the block inputs and/or sizes for the block outputs.
Component:MATLAB Function | Category:Coder error
The sizes of Xq and Yq must match. To interpolate on a grid, these inputs must be the outputs of MESHGRID.
Function 'MATLAB Function' (#35.1732.1767), line 8, column 6:
"interp2(AA,BB,CC',Temp,BB,'linear')"
Launch diagnostic report.
I am using Matlab 2017b
@Michael Goebel I don't know Simulink at all but based on the error message, this should fix it:
[AAexpanded,BBexpanded] = meshgrid(AA,BB);
ZZ = interp2(AAexpanded,BBexpanded,CC',Temp,BB,'linear');
Didnt work, same Error :(
But i found another sulotion:
  • use of "griddata" instead of "interp2"
  • add "coder.extrinsic('griddata');" at the top of the matlab function
  • BB1 = 1; to Initialize the output at the top of the matlab function
It looks like the problem is coder and not simulink. Is simulink invokes coder automatically in some circumstances?
Srinivasan
Srinivasan on 18 Sep 2023
Edited: Srinivasan on 18 Sep 2023
@Michael Goebel Thank you so much. Good find. Helped me a lot...
My pleasure! I'm happy this helped

Sign in to comment.

More Answers (1)

Fangjun Jiang
Fangjun Jiang on 8 Aug 2011

1 vote

To use non codegen supported functions, you need to declare eml.extrinsic('function_name'), but that is not what I am suggesting.
I recommend you creating a 2D lookup table data using the code above in MATLAB, making A and C as inputs, choosing 10 points for A and 9 points for C for example. You just need to do this once and then you can use a lookup table block in your Simulink model.

7 Comments

I've got the same issue however don't understand your words...What do you mean 10 points for A and 9 points for C? Sorry for the stupid question, new to simulink.
The mention of 10 points or 9 points is just an example. Owen was trying to put the code in the answer into an Embedded MATLAB Function in a Simulink model. I was trying to say not to do that as the EMF is going to be executed at every time step. I expect this look-up table reversing only needs to be done once. Once you reverse the table and get the desired look-up table data, you can use the Simulink look-up table block to do the interpolation.
I understand when you said trying to avoid EMF, however didn't understand how to build the matrix with A, C as inputs. I presume if A is a 10 points array and C is a 9 one, we'll need B1 a 10X9 matrix, right?
Yes, I usually try to make the number of rows and columns to be different so it's easier to identify column vs. row.
ok, but could you explain a little more in detail about how to make this B1 matrix? Thanks a lot.
That is the code in the accepted answer. I've updated the answer to reflect a correction from the comments (due to the mix of row and column).
If that is not your use case, you may want to ask a separate question.
I think I got your idea. Just use lookup table dynamic to build another lookup table of Z and B, right?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!