是否可以只保存对称矩阵的一半来节省内存?

时间:2011-06-07 06:20:51

标签: matlab matrix large-data

Ax=b类型问题中使用了一个大矩阵。 A 是对称的。是否有任何算法让我们只保存矩阵的一半并在其上执行x=A\b之类的操作?

3 个答案:

答案 0 :(得分:6)

你只能节省一半的内存,但你可以通过创建矩阵的平面版本来保存,然后取消它。请注意,所需的额外时间可能不会使保存变得有价值:

% pretend this is symettric...
A = rand(10, 10);

% store it as a flat list
flatA = [];
for k = 1:size(A,1)
    flatA = [flatA; A([1:k],k)];
end

save('flatA.mat', 'flatA');

% undo
N = (-1 + (1+4*2*length(flatA))^0.5)/2;
newA = NaN(N,N); 
cur = 1;
for k = 1:N
    len = k;
    newA(1:len, k) = flatA(cur:cur+len-1);
    cur = cur + len;
end
% real A cannot have NaNs or this trick fails
newA(isnan(newA)) = newA(isnan(newA'))';

答案 1 :(得分:3)

这是一个想法,但我还没有测试过。如果你的对称矩阵是正定的,那么对称矩阵A的Cholesky分解,给你A = U * U'。如果使用MATLAB的内置稀疏矩阵将U存储为稀疏矩阵,则可以获得所需的一切,并且使用了大约一半的内存。由于它使用MATLAB的稀疏矩阵类型,您可以使用标准MATLAB函数对其进行操作,只要您记住A = U * U'

例如,要计算A * x = b,请使用x = U'\ U \ b。与其他提出的解决方案不同,MATLAB实际上永远不会在内部使用完整矩阵,甚至会使用加速求解器,这将利用您只用三角形求解的事实。成本是解决单个系统的问题,实际上你已经运行了两次反斜杠运算符(参见上文)。但是,这是你从未实例化完整矩阵所付出的代价。

答案 2 :(得分:1)

如果提取上三角形部分并转换为稀疏矩阵,则应节省内存。这种技术相当快。

% Create a symmetric matrix
A = rand(1000);
A = A + A';

% Extract the upper triangular part
B = sparse(triu(A))              % This is the important line, the rest is just checking.

% Undo
BB = full(B);
C = BB + BB' - diag(diag(BB));

% Check correct
assert(all(A(:) == C(:)));

% Save matrices
save('A.mat', 'A');
save('B.mat', 'B');

% Get file sizes
infoA = dir('A.mat'); infoA.bytes
infoB = dir('B.mat'); infoB.bytes

编辑澄清木片的事情

上述解决方案演示了一种以较少文件空间保存矩阵的方法。矩阵B也比原始矩阵A占用更少的内存。如果你想在B上做线性代数运算,那就非常有效。比较

b = rand(1000);
fullTriUA = triu(A);
sparseTriUA = sparse(fullTriUA);  %same as B above
fullResult = fullTriUA\b;
sparseResult = sparseTriUA\b;
assert(all(fullResult(:) == sparseResult(:)))