我有一组数据点(data_x,data_y)。我需要在这个数据中加入模型函数。模型是5个参数的函数,我已经定义了它:
function F = model(x,xdata)
fraction1 = x(4);
fraction2 = x(5);
fraction3 = 1-x(4)-x(5);
F=1-(fraction1.*(exp(-(xdata)./x(1)))+(fraction2.*(exp(-(xdata)./x(2))))+(fraction3.*(exp(-(xdata)./x(3)))));
参数x(4)和x(5)用于定义三个分数,因此它们的总和必须为1.为了适应这个函数,我使用了lsqcurvefit,就像那样:
%% initial conditions
a0 = [guess1 guess2 guess3 0.3 0.3];
%% bounds
lb = [0 0 0 0 0 ];
ub = [inf inf inf 1 1];
%% Fitting options
curvefitoptions = optimset( 'Display', 'iter' );
%% Fit
a = lsqcurvefit(@model,a0,x,y,lb,ub,curvefitoptions);
问题是不知道如何添加约束,以保持分数的总和= 1.我知道lsqcurvefit
不是解决此问题的最佳解决方案,但我不知道如何提供fmincon
用这些数据查找我的参数。
非常感谢您的帮助!
编辑: 只是一个注释,F的最大值可能是1 ...我试图欺骗,即通过添加甚至乘以10 ^(1-fraction1-fraction2-fraction3)之类的东西,然后我最终得到了几乎等分(0.33),什么都没有意义,导致其他参数被搞砸...当我使用Origin(相同的模型+约束)拟合相同的数据时,它完美地工作...当我使用固定的Origin输出分数参数拟合也很好,但是...它不是那种方法,有十几个适合做:(
答案 0 :(得分:2)
如果你使用fmincon(并使用另一个参数作为第三个分数),则约束非常简单。您可能需要使用fmincon选项来获得良好的收敛。
function solution = my_fit_fun(xdata, ydata, a0)
lb = [0 0 0 0 0 0];
ub = [inf inf inf 1 1 1];
%Aeq and beq specify that the last three parameters add to 1
Aeq = [0 0 0 1 1 1];
beq = 1;
solution = fmincon(@objective,a0,[],[],Aeq,beq,lb,ub);
function F = model(x)
fraction1 = x(4);
fraction2 = x(5);
fraction3 = x(6);
F=1-(fraction1.*(exp(-(xdata)./x(1)))+(fraction2.*(exp(-(xdata)./x(2))))+(fraction3.*(exp(-(xdata)./x(3)))));
end
function f = objective(x)
yfit = model(x);
f = sum((yfit - ydata) .^2);
end
end
答案 1 :(得分:0)
不幸的是,MATLABs lsqcurvefit不支持除下限和上限之外的约束。从数学上讲,这是可能的 - 它只是没有实现。建议不要使用fmincon进行曲线拟合。
在简单求和约束的情况下,最佳解决方案可能是消除变量x(5):
fraction1 = x(4);
fraction2 = 1-x(4);
这通常需要调整x(4)的允许范围,以便x(5)= 1-x(4)也将保持在允许的范围内。 (在你的情况下,对于x(4)和x(5),这是0 ... 1,因此不必进行调整)。