手动计算伪逆

时间:2013-05-24 18:54:26

标签: matlab

我遵循wiki上的公式:

http://en.wikipedia.org/wiki/Pseudo_inverse

计算伪逆但我无法收到正确的结果。例如: 我想找到等式的thetaY=R*theta,我在matlab上写道:

R = -[1/sqrt(2) 1 1/sqrt(2) 0;0 1/sqrt(2) 1 1/sqrt(2);-1/sqrt(2) 0 1/sqrt(2) 1];
% R is 3x4 matrix

Y = [0; -1/sqrt(2);-1]; %Y is 3x1 matrix

B1 = pinv(R);
theta1 = B1*Y;
result1 = R*theta1 - Y

B2 = R'*inv(R*R');
theta2 = B2*Y;
result2 = R*theta2 - Y

这就是结果:

   result1 =
   1.0e-15 *
   -0.1110
   -0.2220
   -0.2220
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND =  1.904842e-17. 
> In pseudoinverse at 14 
result2 =
    0.1036
   -0.1768
   -0.3536

Cleary,theta2是错误的答案,但我不知道如何以及为什么。我读了很多书,他们给了我和维基一样的公式。 任何人都可以帮我做手工伪逆?谢谢!

3 个答案:

答案 0 :(得分:4)

代数告诉你,伪逆可以用来解决这些方程,但代数不能解释有限精度计算。

事实上,使用矩阵乘法计算伪逆是不合适的,因为它在数值上是不稳定的。使用\运算符进行矩阵除法,如

theta = R \ Y;

代数地,矩阵除法与伪逆的乘法相同。但是MATLAB的实现要稳定得多。

有关更多信息,包括稳定方法,请参阅

答案 1 :(得分:1)

正如Ben所说,矩阵求逆在数值上是不稳定的。除非您希望获得矩阵的实际反转,否则不建议使用函数inv,例如参见this link。滥用inv是数字线性代数的新生常犯的错误。

在大多数线性代数计算中,您可以通过使用数值稳定算法来绕过inv。例如,我们有线性求解器的LU分解,普通最小二乘的QR或SVD方法。

答案 2 :(得分:0)

您未正确计算B1。在你的情况下

B1 = inv(R'*R)*R';

因为R领先(传统上它是另一种方式)。但是,这并不能解决你的奇点问题。

pinv使用SVD计算伪逆,你可以读到here

所以基本上它以更优雅的方式做到了:

[U,S,V] = svd(R);
S(abs(S)<(sum(sum(S))*1e-8)) = 0; % removes near-singular values.
Stemp = 1./S;
Stemp(isinf(Stemp)) = 0; % This take the inverse of non-zero terms... I'm sure there is faster way
B1 = V * Stemp' * U';

然后你可以继续前进......