Matlab 中带有一些系数约束的多项式拟合

6
我有一些数据需要使用以下函数进行插值:

f(x) = ax4 + bx2 + c

其中 a > 0b ≤ 0. 不幸的是,MATLAB 的polyfit不允许多项式系数有任何限制。有没有人知道是否有一个 MATLAB 函数可以实现这个功能?否则,我应该怎样实现它?
非常感谢您的帮助。
Elisabetta

为什么要用a>0而不是a>=0?假设你的优化结果为a=0,那么将其设置为a=\epsilon将会改变很少... - Shai
是的,你说得对,我之所以说a>0只是因为我的数据从来没有像一个接近0的函数一样“表现”,但我不一定要将其设置为约束条件。 - bettaberg
@bettaberg:我还是很想知道这些约束条件来自哪里...?你试图建模什么,为什么对参数施加约束? - Rody Oldenhuis
3个回答

11

你可以尝试使用fminsearchfminunc手动定义你的目标函数。

或者,您可以稍微改变问题的定义:

f(x) = a2x4 - b2x2 + c

现在,新的ab可以进行无约束优化,同时确保您要寻找的最终ab是正数(负数的相应情况)。


7

没有限制条件,问题可以被写成和解决为一个简单的线性系统:

% Your design matrix ([4 2 0] are the powers of the polynomial)
A = bsxfun(@power, your_X_data(:), [4 2 0]);

% Best estimate for the coefficients, [a b c], found by 
% solving A*[a b c]' = y in a least-squares sense
abc = A\your_Y_data(:)

如果受约束的模型确实支撑您的数据,那些限制当然会自动得到满足。例如,

iff指的是如果和仅当的逻辑运算符。
% some example factors
a = +23.9;
b = -15.75;
c = 4;

% Your model
f = @(x, F) F(1)*x.^4 + F(2)*x.^2 + F(3);

% generate some noisy XY data
x = -1:0.01:1;
y = f(x, [a b c]) + randn(size(x));

% Best unconstrained estimate a, b and c from the data
A = bsxfun(@power, x(:), [4 2 0]);
abc = A\y(:);

% Plot results
plot(x,y, 'b'), hold on
plot(x, f(x, abc), 'r')
xlabel('x (nodes)'), ylabel('y (data)')

enter image description here

但是,如果您对数据进行的约束与那个受限制的模型描述不准确,可能会出现问题:

% Note: same data, but flipped signs 
a = -23.9;
b = +15.75;
c = 4;

f = @(x, F) F(1)*x.^4 + F(2)*x.^2 + F(3);

% generate some noisy XY data
x = -1:0.01:1;
y = f(x, [a b c]) + randn(size(x));

% Estimate a, b and c from the data, Forcing a>0 and b<0
abc = fmincon(@(Y) sum((f(x,Y)-y).^2), [0 0 0], [-1 0 0; 0 +1 0; 0 0 0], zeros(3,1));

% Plot results
plot(x,y, 'b'), hold on
plot(x, f(x, abc), 'r')
xlabel('x (nodes)'), ylabel('y (data)')

enter image description here

这个解决方案中的a == 0表明模型选择错误。

如果a == 0的精确相等是一个问题:当然,如果您将a == eps(0),则没有区别。从数值上讲,对于现实世界的数据,这并不会被注意到,但它仍然是非零的。

总之,我怀疑你的模型选择不合适,约束条件只是为了让一切正常运行,或者在尝试任何拟合之前应将数据进行无偏/重新缩放,或者某些类似的前提条件适用(我经常看到人们做这种事情,所以是的,我有点有偏见 :)

那么...这些约束背后的真正原因是什么?


“说“既然我们假设了这个模型,约束条件应该被数据自动满足”有点天真了。” - Shai
@Shai:我确切地说了什么?那里有一个非常明确的IF... - Rody Oldenhuis
我可能应该重新措辞我的评论,但重点是:如果您的参数有限制条件,您应该使用它们,而不是希望它们会奇迹般地满足... - Shai
最重要的是:+1 为详细解决方案。 - Shai
是的,我明白 :) 其实我并不是一个专家级的Matlab用户,我找到的最佳多项式函数拟合方式是polyfit,它甚至不能将x和x^3的系数设置为0.. a>0和b<=0的事实直接来自我的数据,因此我不一定要将其作为约束条件,我想.. 如果我表达问题的方式有些模糊,那么很抱歉,并感谢您的帮助,现在一切都清楚了! :) - bettaberg

3
如果您拥有曲线拟合工具箱,那么fit可以使用“上限”和“下限”选项设置约束条件。您需要的是这样的内容。
M=fit(x, f, 'poly4', 'upper', [-inf, 0, -inf, 0, -inf], 'lower', [0, 0, 0, 0, -inf]);

请使用-inf来设置特定系数的无约束条件。
这将提供一个具有相关系数的cfit对象。您可以使用例如M.p1访问这些系数,以获取x ^ 4项。或者,您可以使用feval在任何要求的点处评估函数。
我认为您也可以使用优化工具箱中的lsqcurvefit进行类似的操作。

这是最快、最简单的方法来做到这一点。 - Kvothe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接