Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 求解大型稀疏线性系统,其中A是kron乘积的结果_Matlab_Sparse Matrix_Lazy Evaluation_Tensor_Equation Solving - Fatal编程技术网

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

Matlab 求解大型稀疏线性系统,其中A是kron乘积的结果,matlab,sparse-matrix,lazy-evaluation,tensor,equation-solving,Matlab,Sparse Matrix,Lazy Evaluation,Tensor,Equation Solving,如何解线性系统(A⊗ B+C⊗ D) x=b在MATLAB中,不计算乘以x的实际矩阵(⊗ 表示kronecker乘积)。尽管A、B、C和D是稀疏的矩阵,但这种天真的方法 x = (kron(A,B) + kron(C,D))\b 不适合内存,并导致MATLAB对大型矩阵(每个矩阵约1000 x 1000个元素)崩溃 对此可以做些什么?看看你的矩阵通常是多么的稀疏,张量积的最终结果应该不会占用那么多内存。这是由于中间计算的巨大内存需求而无法进行矢量化的情况之一,但使用循环(和部分矢量化)可能是

如何解线性系统
(A⊗ B+C⊗ D) x=b
在MATLAB中,不计算乘以x的实际矩阵(⊗ 表示kronecker乘积)。尽管
A
B
C
D
稀疏的
矩阵,但这种天真的方法

x = (kron(A,B) + kron(C,D))\b 
不适合内存,并导致MATLAB对大型矩阵(每个矩阵约1000 x 1000个元素)崩溃


对此可以做些什么?

看看你的矩阵通常是多么的稀疏,张量积的最终结果应该不会占用那么多内存。这是由于中间计算的巨大内存需求而无法进行矢量化的情况之一,但使用循环(和部分矢量化)可能是可行的

请注意,这是一种“总比什么都没有好,但不是一种非常好的解决方案”

我将使用,因为它使使用稀疏矩阵更容易

%创建一些矩阵
[A,B]=交易(稀疏(10001000));
A(randperm(1000^2,10000))=randn(1E4,1);
B(randperm(1000^2,10000))=randn(1E4,1);
A=nda(A);B=ndb(B);
%Kronecker张量积,复制自kron.m
[ma,na]=尺寸(A);
[mb,nb]=尺寸(B);
A=重塑(A[1 ma 1 na]);
B=重塑(B,[mb 1 nb 1]);
%K=重塑(A.*B,[ma*mb na*nb]);%这会失败,内存太多。
K=ndSparse(稀疏(mb*ma*nb*na,1),[mb,ma,nb,na]);%这很有效
根据可用内存,可以从这里开始:

%如果内存充足(2D x 1D->3D):
对于ind1=1:mb
K(ind1,:,:,:)=bsxfun(@times,A,B(ind1,:,,:);
结束
%如果内存较少(1D x 1D->2D):
对于ind1=1:mb
对于ind2=1:ma
K(ind1,ind2,:,:)=bsxfun(@times,A(:,ind2,:,:),B(ind1,:,,:);
结束
结束
%如果内存更少(1D x 0D->1D):
对于ind1=1:mb
对于ind2=1:ma
对于ind3=1:nb
K(ind1,ind2,ind3,:)=bsxfun(@times,A(:,ind2,:,:),B(ind1,:,ind3,:);
结束
结束
结束
%如果绝对没有内存(0D x 0D->0D):
对于ind1=1:mb
对于ind2=1:ma
对于ind3=1:nb
对于ind4=1:na
K(ind1,ind2,ind3,ind4)=A(:,ind2,:,ind4)。*B(ind1,:,ind3,:);
结束
结束
结束
结束
K=稀疏(重塑(K[ma*mb na*nb]);%最后一击
因此,这只是一个如何最终执行计算的理论演示,但不幸的是,它非常低效,因为它必须反复调用类方法,而且它也不能保证有足够的内存来计算
\
运算符

改进这一点的一种可能方法是以某种分块方式调用
matlab.internal.sparse.kronSparse
,并将中间结果存储在输出数组的正确位置,但这需要仔细考虑


顺便说一句,我试着使用Ander提到的FEX提交(),但是当你需要计算
kron(A,B)+kron(C,D)
(虽然对于
kron(A,B)\B
的情况来说这很神奇。)

你知道有什么算法可以解决这类问题,并且正在寻找它们在MATLAB中的实现吗?或者你在问,一般来说,如何在MATLAB中解决不适合内存的问题?如何解决不适合内存的问题。或者如何创建一个“矩阵对象”来存储(a x B+C x D)的结果,而不首先明确地计算它,这可以与反斜杠运算符一起使用,如果这是可能的,则可以为此类问题提供一个通用解决方案。然而,如果这个方程代表了一些已知的问题,那么可能有一些有效的实现,它们采用
A、B、C、D
B
并返回
x
w/o来解决整个系统。你可能想提到这个方程出现在哪个领域……方程产生于时空有限元法,其中B和D是质量和刚性矩阵,A和C是时间离散化的矩阵。后两种是只有一个或两个次对角线的稀疏对角矩阵。中介绍了一种求解此类方程的方法,但我正在寻找另一种方法。根据Mathworks,它们没有稀疏的
kron
。在同一个线程中,有一个指向用户实现的稀疏kron的链接,我建议使用该链接