问题很简单。将四次曲线拟合到某些噪声数据。 Mldivide为系数提供了错误的值集,而伪逆的直接计算则有效。
四次方程:c0 + c1 * t + c2 * t ^ 2 + c3 * t ^ 3 + c4 * t ^ 4
输入文件包含每个样本的t和实际值。
fid = fopen('Data_Corr.txt');
A = zeros(4001,5);
for i = 1:4001
dataPt = fscanf(fid,'%f',2);
A(i,:) = [1 dataPt(1) dataPt(1)^2 dataPt(1)^3 dataPt(1)^4];
b(i) = dataPt(2);
end
%c = b\A; %using matlab mldivide
c = inv(A'*A)*A'*b; %computing pseudo inverse directly
for i = 1:4001
d(i) = A(i,1)*c(1) + A(i,2)*c(2) + A(i,3)*c(3) + A(i,4)*c(4) + A(i,5)*c(5);
end
figure; hold on; grid on;
plot(b,'-b');
plot(d,'r-');
答案 0 :(得分:3)
如果我正确解释您的公式和代码,A
代表t的权力,b
包含您尝试建模的数据。使用c
作为系数向量,因此要解决的等式将是
b = A * c
使用mldivide
解决此问题会导致
c = A \ b
使用pinv
解决问题时会导致
c = pinv(A) * b
您的代码包含与这两个等式中的第二个对应的行,格式为c = inv(A'*A)*A'*b
。但是,使用反斜杠操作符是错误的方法。
我强烈怀疑您的不匹配来自此错误。
如果纠正后仍然存在不匹配,则第二种可能性是您的线性系统没有被数据充分确定。在这种情况下,使用pinv
得到系数最小平方和sum(c .^ 2)
的解,而mldivide
产生一个零系数的解,一个“稀疏”解。正如@Dmitry所指出的,这种解决方案究竟是如何得出的,取决于所涉及的矩阵的精确性质。一个例子:
A = [1 2 0; 0 4 3];
b = [8; 18];
c_mldivide = A \ b
c_pinv = pinv(A) * b
给出输出
c_mldivide =
0
4
0.66666666666667
c_pinv =
0.918032786885245
3.54098360655738
1.27868852459016
由于系统的3个系数仅受2个数据点的约束,因此可以有效地自由选择其中一个。
在你的情况下,我怀疑是这种情况,因为具有5个系数的线性系统应该由4001个数据点很好地确定,除非数据是高度冗余的。