1

问题很简单。将四次曲线拟合到一些嘈杂的数据。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-');
4

1 回答 1

4

如果我正确解释了您的公式和代码,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 个数据点很好地确定,除非数据是高度冗余的。

于 2013-10-05T13:23:02.423 回答