令为具有实数的矩阵,令为增加一列。从线性代数我们知道
但是如果有双精度条目并且是数值库中常用的函数怎么办?
最流行的排名函数似乎是 MATLAB 中的函数,它将排名计算为大于特定容差的奇异值的数量。默认的似乎是经过仔细选择的。
Q1:MATLAB 的是否满足上述条件?
有更聪明的选择吗?
令为具有实数的矩阵,令为增加一列。从线性代数我们知道
但是如果有双精度条目并且是数值库中常用的函数怎么办?
最流行的排名函数似乎是 MATLAB 中的函数,它将排名计算为大于特定容差的奇异值的数量。默认的似乎是经过仔细选择的。
Q1:MATLAB 的是否满足上述条件?
有更聪明的选择吗?
Q1:不。这是一个反例:
>> A = eye(4)*1e-300
A =
1.0e-300 *
1.0000 0 0 0
0 1.0000 0 0
0 0 1.0000 0
0 0 0 1.0000
>> rank(A)
ans =
4
>>
>> rank([A, ones(4, 1)])
ans =
1
>>
因此,如果添加的列足够大,它可以使矩阵看起来秩为 1。
Q2。这似乎不太可能。的奇异值是:
>> svd([A, ones(4, 1)])
ans =
2
1e-300
1e-300
5.00000000000001e-301
你可以简单地设置tol = 0(如果你下溢,即使这样也会失败),但除此之外,我很难想象tol在这种情况下,一个聪明的选择会产生除了 1 之外的任何东西。
编辑:(回应OP的评论)
一个更微妙的例子,列规范为
n = 3;
for i = 1:1000
% the following A should have rank(A) == 1 and column norms O(1)
A = orth(randn(n))*diag([1; n*eps*ones(n-1, 1)*0.95])*orth(randn(n));
if rank(A) == 1
i, A
break
end
end
assert(i<1000)
% find a column that makes the augmented matrix rank more than 2
for i = 1:1000
AAug = [A, randn(n, 1)];
if rank(AAug) > 2
i, AAug
break
end
end
assert(i<1000)
fprintf('rank(A) = %d, rank(AAug) = %d\n', rank(A), rank(AAug))
这是我的输出:
i =
1
A =
-0.046045803605795 0.358096260855252 0.167217577109151
0.0939153553990513 -0.730375733980246 -0.34105818453341
0.0495185833028385 -0.385103921204328 -0.179829145619174
i =
35
AAug =
-0.046045803605795 0.358096260855252 0.167217577109151 1.25773638573877
0.0939153553990513 -0.730375733980246 -0.34105818453341 -0.728182736925861
0.0495185833028385 -0.385103921204328 -0.179829145619174 1.19290445411165
rank(A) = 1, rank(AAug) = 3
通常,您可以拥有一个列范数的矩阵,该矩阵几乎是 rank-1,但是添加一列可能会扰乱多个奇异值超出容差。