MATLAB:使用另一个矩阵作为列键/索引处理LARGE矩阵的特定列

rks48beu  于 2023-03-03  发布在  Matlab
关注(0)|答案(1)|浏览(180)

我有一个6行x40列的矩阵A,其中填充了随机数,我使用nchoosek(1:40,6)创建了一个矩阵B,其中包含了列的所有可能的线性组合的索引;一种可能的组合是(1,2,3,4,5,6)和(1,2,3,4,5,40)。该矩阵的大小是3838380 × 6。
但是,矩阵B只给出了要生成的矩阵的索引,也是3838380 x 6,并且包含使用B的值进行索引的A的实际值。例如,B的第4行是[1 2 3 4 5 9]。
对于矩阵B的所有3838380行,我需要使用A创建一个矩阵C。这个新矩阵C使用B的一行作为索引来检索A的列,从而生成一个6x6矩阵:

[1     2     3     4     5     9] --> [0.4178    0.6562   -0.8633    0.7979   -0.9162    0.8720
    0.4864    0.0149   -0.8301   -0.2927   -0.7153   -0.2214
    0.7994   -0.2677   -0.8633   -0.7596   -0.8468   -0.7657
   -0.8695   -0.5467   -0.1804    0.1382    0.4811   -0.5192
   -0.3282    0.0697   -0.7532    0.7501   -0.0869    0.3698
   -0.9913   -0.4210   -0.1140   -0.3029    0.3365    0.6785].

C用于求解Cx = d中的x,其中d是6x1向量。
我使用了一个For循环来执行这个操作3838380次:

for j = 1:length(B) %
    C = A(:,B(j,:))
    x = C\d % d is a 6x1 vector - x returns a 1x6 vector as well
end

目前大约需要3分钟的时间来完成这项工作。我想知道是否有更快的或矢量化的方法,也许创建一个6 x 3838380 x 6的三维矩阵(每个条目都是一个6x6矩阵)?我仍然需要单独处理每个6x6矩阵,并将返回的矢量存储到另一个矩阵中。

    • 失败/我该怎么做?**我实际上尝试创建6 x 3838380 x 6矩阵,完全使用C = A(:,B)。它不适合我的计算机,也不适合我的大脑--我很难弄清楚分解这个巨大的矩阵与我以前所做的有什么不同。

我觉得有一种方法可以做到这一点没有for循环。
干杯!

mzillmmw

mzillmmw1#

这可以通过创建一个大小为6×6×3838380的3D数组来矢量化,该数组包含所有6×6矩阵作为“页面”,然后使用pagemldivide(在R2022a中引入)一次性求解所有线性系统:

% Example data
A = rand(6, 40);
d = rand(size(A,1), 1);
B = nchoosek(1:size(A,2), size(A,1));

% Non-vectorized approach
tic
x = NaN(size(A,1), size(B,1)); % initiallize
for jj = 1:length(B) %
    C = A(:, B(jj,:));
    x(:, jj) = C\d;
end
toc

% Vectorized approach
tic
CC = reshape(A(:, B.'), size(A,1), size(A,1), []);
xx = permute(pagemldivide(CC, d), [1 3 2]);
toc

% Check
isequal(x, xx)

矢量化的版本看起来确实更快。我在R2022b中得到了这些结果(使用Matlab在线):

Elapsed time is 10.310424 seconds.
Elapsed time is 0.812846 seconds.
ans =
  logical
   1

相关问题