我正在尝试使用MATLAB fmincon函数解决问题。我有一个如下所示的等式,我已经使用一些时间点生成了测试数据。我想基于生成的测试数据,通过使用优化来估计参数x(1),x(2)和x(3)。使用fmincon当前估计的参数不接近我用于生成数据的初始参数。任何帮助将受到高度赞赏。
测试数据; 时间点= [10:10:300,500,700,1000]; x = [0.1,0.5,0.3]; %感兴趣的参数 数据= x(1)* sin(x(2)。*时间点)+ log(x(3)。*时间点); %使用测试方程生成数据
% Parameters used to run the fmincon
x0 = [0, 0.1, 0.1]; % initial guess
lb = zeros(1, length(x0)); % lower bound of parameters
ub = ones(1, length(x0)); % upper bound of parameters
[x, fval, exitflag, output] = fmincon(@modelA1, x0, [], [], [], [], lb, ub, [], options, Timepoints, Data);
function fvalues = modelA(x, Timepoints, fvals)
Fvalues = zeros(1, length(Timepoints));
PreFvalues = zeros(1, length(Timepoints));
for Temp = 1:length(Timepoints)
tempY = x0(1)*sin(x0(2).*Timepoints(Temp))+log(x0(3).*Timepoints(Temp));
PreFvalues(Temp) = (fvals(Temp)-tempY)^2;
end
fvalues=sqrt(sum(PreFvalues));
答案 0 :(得分:0)
提供代码示例时,至少要确保它有效,并包含定义测试数据的代码。
经过适当修改以使其正常工作后,以下代码显示代码生成的解决方案非常好。你有一个非常非线性的函数,因此解决方案是局部最小值而不是全局最小值(即原始解决方案)并不奇怪。根据初始条件(即x0),你会得到略微不同的结果。
对于这个问题,我还建议使用lsqcurvefit
而不是fmincon
。这方面的一个例子也在代码中。
function test
Timepoints = [10:10:300, 500, 700, 1000]; x = [0.1, 0.5, 0.3];
Data = x(1)*sin(x(2).*Timepoints)+log(x(3).*Timepoints);
options = optimoptions('fmincon');
% Parameters used to run the fmincon
x0 = [0, 0.1, 0.1]; % initial guess
lb = zeros(1, length(x0)); % lower bound of parameters
ub = ones(1, length(x0)); % upper bound of parameters
[x, fval, exitflag, output] = fmincon(@modelA, x0, [], [], [], [], lb, ub, [], options, Timepoints, Data);
% Using lsqcurvefit
F = @(x,xData)x(1)*sin(x(2).*xData)+log(x(3).*xData);
x = lsqcurvefit(F,x0,Timepoints,Data,lb,ub);
plot(...
Timepoints,Data,...
Timepoints,x(1)*sin(x(2).*Timepoints)+log(x(3).*Timepoints),...
Timepoints,F(x,Timepoints));
legend({'Original','fmincon','lsqcurvefit'});
function fvalues = modelA(x, Timepoints, fvals)
tempY = x(1)*sin(x(2)*Timepoints)+log(x(3)*Timepoints);
PreFvalues = (fvals-tempY).^2;
fvalues=sum(PreFvalues);
答案 1 :(得分:0)
提供代码示例时,至少要确保它有效,并包含定义测试数据的代码。
经过适当修改以使其正常工作后,以下代码显示代码生成的解决方案非常好。你有一个非常非线性的函数,因此解决方案是局部最小值而不是全局最小值(即原始解决方案)并不奇怪。根据初始条件(即x0),你会得到略微不同的结果。
对于这个问题,我还建议使用lsqcurvefit
而不是fmincon
。这方面的一个例子也在代码中。
function test
Timepoints = [10:10:300, 500, 700, 1000]; x = [0.1, 0.5, 0.3];
Data = x(1)*sin(x(2).*Timepoints)+log(x(3).*Timepoints);
options = optimoptions('fmincon');
% Parameters used to run the fmincon
x0 = [0, 0.1, 0.1]; % initial guess
lb = zeros(1, length(x0)); % lower bound of parameters
ub = ones(1, length(x0)); % upper bound of parameters
[x, fval, exitflag, output] = fmincon(@modelA, x0, [], [], [], [], lb, ub, [], options, Timepoints, Data);
% Using lsqcurvefit
F = @(x,xData)x(1)*sin(x(2)*xData)+log(x(3)*xData);
x = lsqcurvefit(F,x0,Timepoints,Data,lb,ub);
plot(...
Timepoints,Data,...
Timepoints,x(1)*sin(x(2).*Timepoints)+log(x(3).*Timepoints),...
Timepoints,F(x,Timepoints));
legend({'Original','fmincon','lsqcurvefit'});
function fvalues = modelA(x, Timepoints, fvals)
tempY = x(1)*sin(x(2)*Timepoints)+log(x(3)*Timepoints);
PreFvalues = (fvals-tempY).^2;
fvalues=sum(PreFvalues);