在 MATLAB 中将 3 维数组操作为 2 维数组的有效方法

Efficient way to manipulate 3 dimensional array to 2 dimensional array in MATLAB

假设A是n_1乘n_1对称矩阵,B是n_2乘n_2对称矩阵,一般是n_1 > n_2 和 n_1 是从 10^3 到 10^5。我想通过 (n_1*n_2) 矩阵 C 得到以下 (n_1*n_2) 使得 C 的每个块都是 C_{ij}=\exp (A\text{.^}2/B_{i,j}^{1.5})/B_{i,j} 其中 i=1, ..., n_2; j=1,...,n_2。

我有两种方法可以在 MATLAB 中计算它,但这两种方法都不能给我令人满意的计时。下面我将给出一个最小的 MATLAB 代码示例。

n1 = 400; n2 = 15;
A = randn(n1); A = A + A' + 10*eye(n1);
B = randn(n2); B = B + B' + 5*eye(n2);

一种方式:

tic;
Atemp = repmat(A, n2, n2);
Btemp = kron(B, ones(n1));
C1 = exp(Atemp.^2./Btemp.^1.5)./Btemp;
toc;
Elapsed time is 2.402167 seconds.

另一种方式:

tic;
Btemp = reshape(B, [1 1 n2*n2]);
Ctemp = bsxfun(@(x,y) exp(x.^2/y.^1.5)/y, A, Btemp);
[a, b, c] = size(Ctemp);
Ctemp = reshape(mat2cell(Ctemp, a, b, ones(c,1)), sqrt(c), sqrt(c));
C2 = cell2mat(Ctemp);
toc;
Elapsed time is 2.923428 seconds.

我想知道在MATLAB中是否有更有效的方法来获取矩阵C? cholesky 分解需要生成的矩阵 C。

顺便说一句,在第二种方法中,必须有更有效的方法(即避免将 Ctemp 转换为单元格,然后将单元格转换为 C2)将 3 维数组 Ctemp 转换为二维数组 C2,但我想不通现在出来了。

非常感谢!

bsxfun 通常没有您预期的那么快。 Cell/mat 重塑也需要一些时间。所以你的第一种方法更好。但是 Atemp.^2./Btemp.^1.5 可以简化为 kron(1./(B.^1.5), A.^2) 以避免一些大的时间矩阵并提高速度。

这是修改后的代码和我机器上的时间。

n1 = 400; n2 = 15;
A = randn(n1); A = A + A' + 10*eye(n1);
B = randn(n2); B = B + B' + 5*eye(n2);

tic;
Btemp = kron(B, ones(n1));
C0 = exp(kron(1./(B.^1.5), A.^2))./Btemp;
toc;

tic;
Atemp = repmat(A, n2, n2);
Btemp = kron(B, ones(n1));
C1 = exp(Atemp.^2./Btemp.^1.5)./Btemp;
toc;

tic;
Btemp = reshape(B, [1 1 n2*n2]);
Ctemp = bsxfun(@(x,y) exp(x.^2/y.^1.5)/y, A, Btemp);
toc;
tic;
[a, b, c] = size(Ctemp);
Ctemp = reshape(mat2cell(Ctemp, a, b, ones(c,1)), sqrt(c), sqrt(c));
C2 = cell2mat(Ctemp);
toc;

Elapsed time is 0.426900 seconds.
Elapsed time is 0.900966 seconds.
Elapsed time is 2.850293 seconds.
Elapsed time is 0.706957 seconds.