我遵循wiki上的公式:
http://en.wikipedia.org/wiki/Pseudo_inverse
计算伪逆但我无法收到正确的结果。例如:
我想找到等式的theta
:Y=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是错误的答案,但我不知道如何以及为什么。我读了很多书,他们给了我和维基一样的公式。 任何人都可以帮我做手工伪逆?谢谢!
答案 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';
然后你可以继续前进......