matlab - 求解巨大的稀疏线性系统,其中 A 是 kron 乘积的结果

标签 matlab sparse-matrix lazy-evaluation tensor equation-solving

如何在 MATLAB 中求解线性方程组 (A ⊗ B + C ⊗ D) x = b 而无需计算与 x 相乘的实际矩阵(⊗ 表示克罗内克产品)。即使 ABCD稀疏矩阵,天真的人方法,

x = (kron(A,B) + kron(C,D))\b 

不适合内存并导致 MATLAB 对于大型矩阵(每个矩阵约 1000 x 1000 个元素)崩溃。

对此可以采取什么措施?

最佳答案

鉴于您的矩阵通常非常稀疏,张量积的最终结果不应占用那么多内存。这是由于中间计算需要大量内存而无法完成矢量化的情况之一,但使用循环(和部分矢量化)可能是可能的。

请注意,这是一种“总比没有好,但好不了多少”类型的解决方案。

我将使用 ndSparse submission ,因为它可以更轻松地处理稀疏矩阵。

% Create some matrices
[A,B] = deal(sparse(1000,1000));
A(randperm(1000^2, 10000)) = randn(1E4, 1);
B(randperm(1000^2, 10000)) = randn(1E4, 1);
A = ndSparse(A); B = ndSparse(B);

% Kronecker tensor product, copied from kron.m
[ma,na] = size(A);
[mb,nb] = size(B);
A = reshape(A,[1 ma 1 na]);
B = reshape(B,[mb 1 nb 1]);
% K = reshape(A.*B,[ma*mb na*nb]);                    % This fails, too much memory.
K = ndSparse(sparse(mb*ma*nb*na,1),[mb, ma, nb, na]); % This works

从这里开始,可以根据可用内存继续操作:

% If there's plenty of memory (2D x 1D -> 3D):
for ind1 = 1:mb
  K(ind1,:,:,:) = bsxfun(@times, A, B(ind1, :, :, :));
end

% If there's less memory (1D x 1D -> 2D):
for ind1 = 1:mb
  for ind2 = 1:ma
    K(ind1,ind2,:,:) = bsxfun(@times, A(:, ind2, :, :), B(ind1, :, :, :));
  end
end

% If there's even less memory (1D x 0D -> 1D):
for ind1 = 1:mb
  for ind2 = 1:ma
    for ind3 = 1:nb
      K(ind1,ind2,ind3,:) = bsxfun(@times, A(:, ind2, :, :), B(ind1, :, ind3, :));
    end
  end
end

% If there's absolutely no memory (0D x 0D  -> 0D):
for ind1 = 1:mb
  for ind2 = 1:ma
    for ind3 = 1:nb
      for ind4 = 1:na
        K(ind1,ind2,ind3,ind4) = A(:, ind2, :, ind4) .* B(ind1, :, ind3, :);
      end
    end
  end
end

K = sparse(reshape(K,[ma*mb na*nb])); % Final touch

所以这只是如何最终执行计算的理论演示,但不幸的是它的效率非常低,因为它必须一遍又一遍地调用类方法,而且它不能保证将有足够的内存来计算 \ 运算符。

改进此问题的一种可能方法是以某种 block 方式调用matlab.internal.sparse.kronSparse,并将中间结果存储在输出数组的正确位置,但这需要一些小心想法。

顺便说一句,我尝试使用 Ander 提到的 FEX 提交 ( KronProd ),但当您需要计算 kron(A,B) + kron(C,D) 时,它没有任何好处(尽管对于 kron(A,B)\b 情况来说这很神奇)。

关于matlab - 求解巨大的稀疏线性系统,其中 A 是 kron 乘积的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56340347/

相关文章:

限制访问 addprop 的 Matlab 动态属性

algorithm - 使用Redis从有限范围内生成唯一ID

python-2.7 - 用 1 填充 Scipy 稀疏矩阵

recursion - Clojure 中的递归惰性序列

haskell - 为什么有时可以从右侧折叠无限列表?

java - 寻找一个好的 Java ODE 求解器

image - 在 MATLAB 7.0.1 (R14SP1) 中使用 XLSREAD 读取大型 Microsoft Excel 文件时出错

matlab - 如何在Matlab中手动分割和标记图像中的ROI?

python - 使用相关矩阵在大型稀疏矩阵上进行 PCA

用于大量条目的 C# LazyList