【问题标题】:Is it possible to save only half of a symmetric matrix to save the memory?是否可以只保存对称矩阵的一半来节省内存?
【发布时间】:2011-09-09 19:36:57
【问题描述】:

Ax=b 类型问题中使用了一个大矩阵。 A 是对称的。有什么算法可以让我们只保存一半的矩阵,然后在上面做x=A\b这样的操作吗?

【问题讨论】:

    标签: matlab matrix large-data


    【解决方案1】:

    您只会节省一半的内存,但您可以通过创建矩阵的平面版本来做到这一点,将其保存,然后将其展开。请注意,所需的额外时间可能并不值得节省:

    % 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'))';
    

    【讨论】:

      【解决方案2】:

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

      % 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(:)))
      

      【讨论】:

      • 是的,但是要使用矩阵,你强制用户转换回一个完整的矩阵,然后无论如何都要恢复整个矩阵!!!!!!这不仅不会节省内存,还会生成多个矩阵副本作为完整矩阵。它占用的内存是原始矩阵所需的数倍。
      • @woodchips:你误会了。矩阵的额外副本仅用于从文件中恢复。查看我的编辑。
      • 是的。但是,当您恢复阵列时,您会创建该阵列的多个副本。存储阵列的磁盘空间很少会成为问题,但 RAM 通常会如此。我将这个问题解释为内存使用问题之一,因为用户仍然希望使用最小化数组来使用 A\b 之类的操作。如果是这样,那么制作大型数组的多个副本肯定会是一个问题。这里需要澄清一下。
      • 只有当原始矩阵的非零元素少于三分之一时,稀疏矩阵才能节省内存。在这种情况下,它超过了一半。试试whos A BB 实际上比 A 占用更多空间。
      • @yuk: 对于 6x6 或更大的矩阵,B 占用的内存少于 A。 (在 R2011a 和 R2010b 上测试。)对于非常大的矩阵,它接近 A 的内存占用量的 3/4。也许你忘了取上三角部分。
      【解决方案3】:

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

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

      【讨论】:

      • 如果您对其进行测试,我会提供代表并提供MWE 以表明它有效!
      猜你喜欢
      • 2018-06-22
      • 2011-04-02
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 2022-10-21
      • 1970-01-01
      • 2015-07-08
      相关资源
      最近更新 更多