简体   繁体   中英

Matlab function in fmincon with fixed value

I have a simple model where I want to minimize the RMSE between my dependent variable y and my model values. The model is: y = alpha + beta'*x .

For minimization, I am using Matlab's fmincon function and am struggling with multiplying my parameter p(2) by x.

MWE:

% data
y = [5.072, 7.1588, 7.263, 4.255, 6.282, 6.9118, 4.044, 7.2595, 6.898, 4.8744, 6.5179, 7.3434, 5.4316, 3.38, 5.464, 5.90, 6.80, 6.193, 6.070, 5.737]
x = [18.3447, 79.86538, 85.09788, 10.5211, 44.4556, 69.567, 8.960, 86.197, 66.857, 16.875, 52.2697, 93.971, 24.35, 5.118, 25.126, 34.037, 61.4445, 42.704, 39.531, 29.988]

% initial values
p_initial = [0, 0];

% function: SEE BELOW

objective = @(p) sqrt(mean((y - y_mod(p)).^2));

% optimization
[param_opt, fval] = fmincon(objective, p_initial)

If I specify my function as follows then it works.

y_mod = @(p) p(1) + p(2).*x

However, it does not work if I use the following code. How can I multiply p(2) with x? Where x is not optimized, because the values are given.

function f = y_mod(p)

f = p(1) + p(2).*x

end

Here is the output from a script that has the function declaration:

>> modelFitExample2a
RMS Error=0.374, intercept=4.208, slope=0.0388

And here is code for the above. It has many commented lines because it includes alternate ways to fit the data: an inline declaration of y_mod() , or a multi-line declaration of y_mod() , or no y_mod() at all. This version uses the multi-line declaration of y_mod() .

%modelFitExample2a.m    WCR 2021-01-19
%Reply to stack exchange question on parameter fitting
clear;
global x    %need this if define y_mod() separately, and in that case y_mod() must declare x global

% data
y = [5.0720, 7.1588, 7.2630, 4.2550, 6.2820, 6.9118, 4.0440, 7.2595, 6.8980, 4.8744...
     6.5179, 7.3434, 5.4316, 3.3800, 5.4640, 5.9000, 6.8000, 6.1930, 6.0700, 5.7370];
x = [18.3447,79.8654,85.0979,10.5211,44.4556,69.5670, 8.9600,86.1970,66.8570,16.8750,...
     52.2697,93.9710,24.3500, 5.1180,25.1260,34.0370,61.4445,42.7040,39.5310,29.9880];

% initial values
p_initial = [0, 0];

%predictive model with parameter p
%y_mod = @(p) p(1) + p(2)*x;

% objective function
%If you use y_mod(), then you must define it somewhere
objective = @(p) sqrt(mean((y - y_mod(p)).^2)); 
%objective = @(p) sqrt(mean((y-p(1)-p(2)*x).^2));

% optimization
options = optimset('Display','Notify');
[param_opt, fval] = fmincon(objective,p_initial,[],[],[],[],[],[],[],options);

% display results
fprintf('RMS Error=%.3f, intercept=%.3f, slope=%.4f\n',...
    fval,param_opt(1),param_opt(2));

%function declaration: predictive model 
%This is an alternative to the inline definition of y_mod() above.
function f = y_mod(p)

global x
f = p(1) + p(2)*x;

end

carl, The second method, in which you declare y_mod() explicitly (at the end of your script, or in a separate file y_mod.m), does not work because y_mod() does not know what x is. Fix it by declaring x global in the main program at the top, and declare x global in y_mod() .

%function declaration
function f = y_mod(p)

global x
f = p(1) + p(2)*x;

end

Of course you don't need y_mod() at all. The code also works if you use the following, and in this case, no global x is needed:

% objective function
objective = @(p) sqrt(mean((y-p(1)-p(2)*x).^2));

By the way, you don't need to multiply with .* in y_mod. You may use * , because you are multiplying a scalar by a vector.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM