Interpolating numerical function of many variables

조회 수: 5 (최근 30일)
erictoleratesMATLAB
erictoleratesMATLAB 2023년 1월 20일
답변: erictoleratesMATLAB 2023년 1월 25일
Hi everyone,
I'm attempting to develop a lookup function/table based on a set of data.
This data describes the measured airflow through a fan as a function of the fan's PWM command and the position of various ducts in the system (airflow = f(PWM,Vent 1 position, Vent 2 position, Vent 3 position, Vent 4 position). This data only exists for configurations where each duct is either open or closed at 100%.
There are 4 ducts, (V, D, F, and S) and I have the airflow values at each combination of ducts open/closed and each PWM command. Assume that when the direction says something like 'V+F+D', all 3 ducts are open at 100%, and if a duct isn't specified (like S in this example) it is fully closed at 0%.
I would like the ability to specify something like (V open at 40%, S open at 20%, D fully closed, F open at 100%, PWM command = 50) and have the output be an interpolated airflow at this set of door conditions. I'm getting stuck trying to format the data in a way that makes the problem solvable. Any advice and tips would be appreciated!
Please find some sample data attached.
Here's what I have so far, but I haven't figured out how to interpolate at vent states I don't yet have data for.
pwm_values = [0, 24, 34, 44, 64, 85]; % [Val out of 85]
duct_openings = {'Off', 'V', 'F', 'D', 'S', 'V+F', 'V+S', 'V+D', 'F+S', 'F+D', 'S+D', 'V+F+S', 'V+F+D', 'V+D+S', 'F+D+S', 'V+F+D+S'};
airflow_matrix = [0 0 0 0 0 0;
0 80.05 96.175 112.6 146.65 171.55;
0 85.75 104.2 122.875 157.975 176.65;
0 92.575 111.1 130.975 165.175 183.625;
0 53.8 64.525 72.85 87.325 97.6;
0 100.975 126.775 154.075 213.55 240.4;
0 80.875 100.975 122.125 160.075 182.125;
0 95.575 121.75 146.875 193.6 226;
0 81.55 101.275 119.725 159.4 179.65;
0 102.55 132.25 160.525 208.825 232.75;
0 93.55 116.725 142.15 1680.4 194.95;
0 106.825 137.95 171.925 226.675 252.175;
0 114.4 147.925 184.525 243.55 271.075;
0 102.55 132.25 160.525 210.775 236.8;
0 97.45 128.425 156.325 210.775 236.8;
0 116.5 150.775 188.125 248.275 276.4;
];
% Create meshgrid of known vals
[X,Y] = meshgrid(pwm_values, 1:size(airflow_matrix,1));
% Transpose to format for griddedInterpolant
X = X';Y = Y';airflow_matrix = airflow_matrix';
% Create lookup entity
F = griddedInterpolant(X,Y,airflow_matrix,'linear');
% Define the PWM value and duct opening combination to test
pwm = 84;
duct_combination = 'V+D+S';
interp_airflow = F([pwm, find(strcmp(duct_openings,duct_combination))])
  댓글 수: 3
erictoleratesMATLAB
erictoleratesMATLAB 2023년 1월 20일
편집: erictoleratesMATLAB 2023년 1월 20일
Hey Torsten, thanks for your response!
I suppose what I'm looking for is the ability to specify any arbitrary duct opening combination and percentage.
For example: What if the opening percentages for the ducts are V=50%,D=50%,F=100%,S=75% and PWM = 34? (The data I provided shows what happens when each respective duct is either at 0 or 100%)
We have data for V,D,F,S=100% and various other combinations, so shouldn't it be possible to somehow interpolate the requested behavior?
Apologies if I'm still unclear, I can try to clarify my question further if helpful
Torsten
Torsten 2023년 1월 21일
편집: Torsten 2023년 1월 21일
For example: What if the opening percentages for the ducts are V=50%,D=50%,F=100%,S=75% and PWM = 34?
And you are optimistic that you can capture such complicated interactions that might occur by percentage openings using a simple interpolation ?
Ok. But then you will have to define V, D, F, S and PWM as independent variables.
What would be an adequate model to get a correlation airflow = f(V,D,F,S,PVM) ?
You have measurements that take interactions between V, D, F and S into account. Thus the model should contain terms
V, D, F, S, V*F, V*S, V*D, F*S, F*D, S*D, V*F*S,V*F*D,V*D*S.
A third-order polynomial of the form
p0*V + p1*D + p2*F + p3*S + p02*V*F + p03*V*S + p01*V*D + p23*F*S + p21*F*D + p31*S*D + p023*V*F*S + p021*V*F*D + p013*V*D*S
comes to mind with coefficients p0,p1,...,p013 to be determined from your measurement data.
But how to integrate PVM here ?

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

채택된 답변

erictoleratesMATLAB
erictoleratesMATLAB 2023년 1월 25일
Hi everyone!
Thank you for your thoughtful answers and responses to my question. I figured out a good solution to this particular problem that address all the key points I originally wanted.
I started by formulating the problem as a matrix problem, attempting to fit a function (CMH) of 5 variables (Door 1, Door 2, Door 3, Door 4, PWM) to the lowest order polynomial that I could reasonably expect to implement (The end goal is to implement this fucntion in C for another personal project).
I treated door 1 (V) as , door 2 (F) as , D as , S as , PWM as and CMH as . I then looped over each CMH value in my matrix, and for that value of CMH () I record the values of each input . When a door position is open, we record it as 1. When the door is closed, we record it at 0. Doing this records every known door state + PWM and the corresponding CMH. The end result is a matrix that looks something like this (the picture is truncated of course, the matrix is much larger):
I then used fitlm to test a bunch of fits, and pick the one that matches the data best with relatively easy implementation. Here are the results:
Here's the code so anyone can try this themselves if they have a similar problem.
% Goal: To obtain airflow = f(PWM,V,D,F,S)
% Where:
% - PWM = PWM Command
% - V = Vent Position (between 0 and 1)
% - F = Foot Position (between 0 and 1)
% - D = Defrost Position (between 0 and 1)
% - S = Seat Position (between 0 and 1)
% - CMH = Measured Airflow through blower [CMH]
clear;close all;clc
%% Hard Code values to be fit
airflow_matrix = [0 0 0 0 0 0
0 93.4 114.9 136.8 182.2 215.4
0 101 125.6 150.5 197.3 222.2
0 110.1 134.8 161.3 206.9 231.5
0 58.4 72.7 83.8 103.1 116.8
0 121.3 155.7 192.1 271.4 307.2
0 94.5 121.3 149.5 200.1 229.5
0 114.1 149 182.5 244.8 288
0 95.4 121.7 146.3 199.2 226.2
0 123.4 163 200.7 265.1 297
0 111.4 142.3 176.2 227.2 246.6
0 129.1 170.6 215.9 288.9 322.9
0 139.2 183.9 232.7 311.4 348.1
0 123.4 163 200.7 267.7 302.4
0 116.6 157.9 195.1 267.7 302.4
0 142 187.7 237.5 317.7 355.2
];
PWM_array = [0, 24, 34, 44, 64, 85];
duct_openings = {'Off', 'V', 'F', 'D', 'S', 'V+F', 'V+S', 'V+D', 'F+S', 'F+D', 'S+D', 'V+F+S', 'V+F+D', 'V+D+S', 'F+D+S', 'V+F+D+S'};
%% Now we try to save them in a productive format
x1 = []; % V
x2 = []; % F
x3 = []; % D
x4 = []; % S
x5 = []; % PWM
CMH = [];% CMH
for i = 2:numel(duct_openings)
% for j = 2:6
for j = 1:numel(PWM_array)
x1 = [x1 contains(duct_openings{i},'V')];
x2 = [x2 contains(duct_openings{i},'F')];
x3 = [x3 contains(duct_openings{i},'D')];
x4 = [x4 contains(duct_openings{i},'S')];
x5 = [x5 PWM_array(j)];
CMH = [CMH airflow_matrix(i,j)];
end
end
% Configure the independent variables into a useful representation
indep_vars = [x1' x2' x3' x4' x5'];
% full_matrix = [x1' x2' x3' x4' x5' CMH'];
%% Now let's try to fit a model to this data
mdl = fitlm(indep_vars,CMH,'quadratic');
%% Let's test this fit in a way actually usable in C. It'll have to be hardcoded,
% so reducing the precision of the coefficients is top priority.
% Truncated from mdl.Coefficients.Estimate to have only 5 digits. This was
% determined as an acceptable precision for maintaining prediction accuracy.
truncated = [-21.03
11.326
0
32.222
-0.790
3.5869
0.0383
-25.16
8.0716
0.8849
-24.70
-4.286
0.9407
1.2133
0.8871
0.0972
0
19.155
0
0
-0.022
];
% Let's create our fit function using our hard coded values
fit_function = @(x1,x2,x3,x4,x5) truncated(1).*1 + truncated(2).*x1 + truncated(3).*x2 + truncated(4).*x3 + truncated(5).*x4 + truncated(6).*x5 + truncated(7).*x1*x2 + truncated(8).*x1*x3 + truncated(9).*x1*x4 + truncated(10).*x1*x5 + truncated(11).*x2*x3 + truncated(12).*x2*x4 + truncated(13).*x2*x5 + truncated(14).*x3*x4 + truncated(15).*x3*x5 + truncated(16).*x4*x5 + truncated(17).*x1.^2 + truncated(18).*x2.^2 + truncated(19).*x3.^2 + truncated(20).*x4.^2 + truncated(21).*x5.^2;
%% Let's compare the set of predictions to the actual data
x1_test = []; % V
x2_test = []; % F
x3_test = []; % D
x4_test = []; % S
x5_test = []; % PWM
CMH_Predicted = [];% CMH
CMH_Predicted_C = [];
for i = 2:numel(duct_openings)
% for j = 2:6
for j = 1:numel(PWM_array)
x1_test = contains(duct_openings{i},'V');
x2_test = contains(duct_openings{i},'F');
x3_test = contains(duct_openings{i},'D');
x4_test = contains(duct_openings{i},'S');
x5_test = PWM_array(j);
pred = feval(mdl, x1_test,x2_test,x3_test,x4_test, x5_test);
pred = min(365, max(0, pred));
C_pred = fit_function(x1_test,x2_test,x3_test,x4_test, x5_test);
C_pred = min(365, max(0, C_pred));
CMH_Predicted = [CMH_Predicted pred];
CMH_Predicted_C = [CMH_Predicted_C C_pred];
end
end
%% Plot comparison
figure;
err = CMH_Predicted-CMH;
neg = (err<0).*err;
pos = (err>=0).*err;
errorbar(1:numel(CMH),CMH, neg,pos,'LineStyle','none','Color','red');hold on
plot(1:numel(CMH),CMH,'db',1:numel(CMH_Predicted),CMH_Predicted,'dr');title(sprintf("RMSE: %0.2f",rms(err)))
xlabel("Num");ylabel("CMH");grid minor;legend("Prediction Error","Data","Prediction");
fprintf("RMSE: %0.2f\n",rms(err))
% figure;plot(mdl);grid minor;improvePlot
%% Plot comparison using a lower fidelity fit (keeping less data points)
figure;
err2 = CMH_Predicted_C-CMH;
neg = (err2<0).*err2;
pos = (err2>=0).*err2;
errorbar(1:numel(CMH),CMH, neg,pos,'LineStyle','none','Color','red');hold on
plot(1:numel(CMH),CMH,'db',1:numel(CMH_Predicted_C),CMH_Predicted_C,'dr');title(sprintf("RMSE: %0.2f",rms(err2)))
xlabel("HVAC Config Index [-]");ylabel("Blower Airflow Prediction [CMH]");grid minor;legend("Prediction Error","Data","Prediction");
fprintf("RMSE: %0.2f\n",rms(err2))
% figure;plot(mdl);grid minor;improvePlot
%% Plot the 2 fits against eachother
figure;
plot(1:numel(CMH),CMH,'dg',1:numel(CMH_Predicted),CMH_Predicted,'db',1:numel(CMH_Predicted_C),CMH_Predicted_C,'dr');title("Comparing High vs Low Precision Data Fit")
xlabel("Num");ylabel("CMH");grid minor;legend("Real Data","High Precision Fit","Low Precision Fit","Prediction");

추가 답변 (1개)

Sulaymon Eshkabilov
Sulaymon Eshkabilov 2023년 1월 21일
You should consider here some sort of unit compatibe value for U, S, D, V. In other words, 100% (and 80%, 60%, 40%, 20%) open U corresponds to ??% of S opening, ??? % D and ??% of V or vice verse 100% open S corresponds to ?% of U, ?% D, ?%V. So then you shall be able to compute V+F, V+S, V+F+D, etc., make up the states of PWM.

카테고리

Help CenterFile Exchange에서 Function Creation에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by