双精度增广矩阵的秩

计算科学 matlab 数字 svd
2021-12-11 17:38:24

为具有实数的矩阵,令增加一列。从线性代数我们知道 但是如果有双精度条目并且是数值库中常用的函数怎么办?AA+A

rank(A+)=rank(A)orrank(A+)=rank(A)+1
Arank()

最流行的排名函数似乎是 MATLAB 中的函数,它将排名计算为大于特定容差的奇异值的数量。默认的似乎是经过仔细选择的。toltol=max(size(A))eps(norm(A))

Q1:MATLAB 的是否满足上述条件?rank()

有更聪明的选择吗?tol

1个回答

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。这似乎不太可能。的奇异值是:A

>> svd([A, ones(4, 1)])
ans =
                         2
                    1e-300
                    1e-300
     5.00000000000001e-301

你可以简单地设置tol = 0(如果你下溢,即使这样也会失败),但除此之外,我很难想象tol在这种情况下,一个聪明的选择会产生除了 1 之外的任何东西。

编辑:(回应OP的评论)

一个更微妙的例子,列规范为O(1)

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,但是添加一列可能会扰乱多个奇异值超出容差。O(1)