我正在尝试编写一个检查矩阵是否正交的方法,如果是,则返回TRUE;如果不是则返回FALSE我的问题是我的isequal()不能正常工作。基本上我可以基于两个公式以两种方式进行检查:
一种方法是检查矩阵R的转置是否等于矩阵R的逆。如果它们相等则它是正交的。 (R'= INV(R))
另一种方法是检查并查看矩阵R乘以矩阵R的转置是否等于R的恒等矩阵。(R'R = I)如果是,那么矩阵是正交的。我大部分时间都在使用isequal()但它仍然会产生错误。有人可以查看我的代码并告诉我为什么会这样吗?
我用Z = orth(randn(3,3))生成随机正交矩阵,我调用我的方法isortho(Z)
function R = isortho(r)
%isortho(R), which returns true if R is orthogonal matrix, otherwise returns false.
if ismatrix(r) && size(r,1)==size(r,2) %checks if input is square matrix
'------'
trans=transpose(r)
inverted=inv(r)
isequal(trans,inverted)
trans==inverted
isequal(transpose(r),inv(r)) %METHOD ONE
i=size(r,1);
I=eye(i) %creating Identity matrix based on size of r
r*transpose(r)
r*transpose(r)==I %METHOD TWO
%check if transpose of r is times inverse of r equals Identity matrix of r
if (r*transpose(r)==I)
R= 'True';
else
R= 'False';
end
end
end
这是我的输出:
>> isortho(Z)
ans =
------
trans =
-0.2579 -0.7291 -0.6339
0.8740 0.1035 -0.4747
0.4117 -0.6765 0.6106
inverted =
-0.2579 -0.7291 -0.6339
0.8740 0.1035 -0.4747
0.4117 -0.6765 0.6106
ans = ////isequal(trans,inverted) which yielded 0 false
0
ans = ////trans==inverted
0 1 0
1 0 0
0 1 1
ans = ////isequal(transpose(r),inv(r))
0
I =
1 0 0
0 1 0
0 0 1
ans =
1.0000 0 0.0000
0 1.0000 0.0000
0.0000 0.0000 1.0000
ans =
1 1 0
1 1 0
0 0 1
ans =
False
>>
有人可以帮我解决这个问题,也可以告诉我为什么当矩阵倒置和反转看起来相同时,isequal()失败了?
答案 0 :(得分:4)
正如评论中所述,您遇到了计算机精度问题。有关详细信息,请参阅Why is 24.0000 not equal to 24.0000 in MATLAB?和http://matlabgeeks.com/tips-tutorials/floating-point-comparisons-in-matlab/。这不是Matlab特有的东西,它是一个计算机的东西,你只需处理它。
在你的情况下,你试图看看两件事是否相等,但这两件事是很多浮点运算的结果。所以他们几乎永远不会完全相同,但应该总是非常接近。所以,设置一个容差,比如1e-12,并说如果它们的差异的某些度量低于该容差,则两个事物是相等的,例如:
norm(r.'-inv(r))<tol
找到两个矩阵之间差异的2范数,然后如果它小于tol
,则计算结果为1,或者为真。
如果我设置tol=1e-12
,那么一切正常。如果我设置tol=1e-15
,一切都很顺利。但如果我设置tol=1e-16
,那么一切都会停止工作!这是因为计算机预测误差的数量大于1e-16,因此norm(r.'-inv(r))
的答案不能精确到该容差。 Matlab可以在我的计算机上区分的最小量大约是2.2x10 ^( - 16),因此你必须确保你的容差设置在这个值之上。当然,设置tol
太大意味着你说某些非正交矩阵是正交的,但我不希望tol=1e-14
给你任何重大问题。