:)我正在尝试编写一个最小二乘算法,我想出了这个:
function [y] = ex1_Least_Squares(xValues,yValues,x) % a + b*x + c*x^2 = y
points = size(xValues,1);
A = ones(points,3);
b = zeros(points,1);
for i=1:points
A(i,1) = 1;
A(i,2) = xValues(i);
A(i,3) = xValues(i)^2;
b(i) = yValues(i);
end
constants = (A'*A)\(A'*b);
y = constants(1) + constants(2)*x + constants(3)*x^2;
当我将这个matlab脚本用于线性函数时,我觉得它很好用。但是,当我通过sin(x)函数的12个点时,我得到了非常糟糕的结果。
这些是我传递给函数的要点:
xValues = [ -180; -144; -108; -72; -36; 0; 36; 72; 108; 144; 160; 180];
yValues = [sind(-180); sind(-144); sind(-108); sind(-72); sind(-36); sind(0); sind(36); sind(72); sind(108); sind(144); sind(160); sind(180) ];
结果是sin(165°)= 0.559935259380508,当它应该是sin(165°)= 0.258819
答案 0 :(得分:1)
没有理由将抛物线拟合到整个正弦波周期应该给出好的结果。这两条曲线是无关的。
答案 1 :(得分:0)
MATLAB已经包含最小二乘多项式拟合函数polyfit
和互补函数polyval
。虽然您可能应该自己编写,但尝试以下内容将具有教育意义:
xValues = [ -180; -144; -108; -72; -36; 0; 36; 72; 108; 144; 160; 180];
% you may want to experiment with different ranges of xValues
yValues = sind(xValues);
% try this with different values of n, say 2, 3, and 4
p = polyfit(xValues,yValues,n);
x = -180:36:180;
y = polyval(p,x);
plot(xValues,yValues);
hold on
plot(x,y,'r');
此外,更一般地说,您应该避免使用代码中的循环。这应该是等效的:
points = size(xValues,1);
A = ones(points,3);
A(:,2) = xValues;
A(:,3) = xValues.^2; % .^ and ^ are different
涉及b
的循环部分等同于执行b = yValues
;要么命名传入的变量b
,要么只使用变量yValues
,不需要复制它。