arrays - 向量化矩阵的按列逻辑索引
问题描述
我正在 MATLAB 中对矩阵进行逐列逻辑索引。一个例子是:
tic
N = 5*10^6;
input = randi(100,N,12);
output = zeros(N,1);
d_sn2 = randi(25,N,12);
d_sd2 = randi(25,N,12);
LL1 = randi(8,N,12);
UL1 = randi([12,20],N,12);
LL2 = randi(8,N,12);
UL2 = randi([12,20],N,12);
for p = 1:N
temp = zeros(12,12);
for i = 1:12
I2 = (d_sn2(:,i)>LL1(p,i) & d_sn2(:,i)<UL1(p,i)) & (d_sd2(:,i)>LL2(p,i) & d_sd2(:,i)<UL2(p,i));
temp(i,:) = mean(input(I2,:));
end
output(p) = max(temp(:));
end
toc
我想知道我是否可以将此操作矢量化或更快?
解决方案
I2
内循环中的计算可以很容易地向量化。这个:
temp = zeros(12,12);
for i = 1:12
I2 = (d_sn2(:,i)>LL1(p,i) & d_sn2(:,i)<UL1(p,i)) & (d_sd2(:,i)>LL2(p,i) & d_sd2(:,i)<UL2(p,i));
temp(i,:) = mean(input(I2,:));
end
与此相同:
I2 = d_sn2>LL1(p,:) & d_sn2<UL1(p,:) & d_sd2>LL2(p,:) & d_sd2<UL2(p,:);
temp = zeros(12,12);
for i = 1:12
temp(i,:) = mean(input(I2(:,i),:));
end
此代码使用隐式单例扩展,如果您有 R2016b 之前的 MATLAB 版本,则需要使用:等编写每个>
( gt
) 和<
( lt
) 调用。bsxfun
bsxfun(@gt,d_sn2,LL1(p,:))
不幸的是,索引到input
向量化要困难得多。因为每次迭代都会访问i
不同数量的元素input
,所以没有简单的方法可以创建temp
没有循环的矩阵。我尝试的几种方法都比循环代码慢得多。
如果您使用的是相当新版本的 MATLAB,那么您的代码将非常高效。MATLAB 的解释器使用 JIT(即时编译器)使循环不像以前那么慢。例如,将矩阵的所有元素相加的普通循环仅比使用函数慢 2-3 倍sum
。回到过去,这曾经可能慢 100 倍。所以矢量化的好处和以前不一样了。再加上您正在使用的非常大的数组,这意味着向量化将是一种悲观化,因为向量化通常意味着创建更大的中间矩阵。
推荐阅读
- javascript - 函数 CollectionRefernce.doc() 要求它的第一个参数是字符串类型
- amazon-web-services - 使用 AWS 反应本机运行错误
- android - E/OpenGLRenderer:字体太大而无法放入缓存 - 使用 AutoSizing TextView 时
- sql - 带子句列表
- assembly - 如何在 SAP2 程序集中将两个十六进制值连接成一个?
- react-native - React Native Scroll View - 在视图之间选择空间时无法滚动
- android - 转义引号android时出现SQL语法错误
- amazon-web-services - 使用自定义 AMI 部署 EC2 队列
- twitter - 如何识别推文中的网址是图片、视频、文章还是推文链接?
- vba - 使用公式从源工作表中粘贴值