通过嵌套循环构造Matlab数组
假设我有三个维度为 mxn
的三个矩阵 A_1
, A_2
, A_3
m 和 n
很大.这些矩阵严格包含正数.
Suppose I have three matrices A_1
, A_2
, A_3
each of dimension mxn
, where m
and n
are large. These matrices contain strictly positive numbers.
我想构造一个尺寸为 mx1
的矩阵 check
,使得对于每个 i = 1,...,m
:
I want to construct a matrix check
of dimension mx1
such that, for each i=1,...,m
:
检查(i)= 1
是否存在 j,k
这样
A_1(i,1)+ A_2(j,1)+ A_3(k,1)
在我的情况下, m
大( m = 10 ^ 5
)而 n = 500
.因此,我希望您能帮助您找到一种有效的方法.
In my case m
is large (m=10^5
) and n=500
. Therefore, I would like your help to find an efficient way to do this.
下面,我重现一个示例.我强加了 m
小于实际值,并报告了构造 check
的不完整且可能无效的尝试.
Below I reproduce an example. I impose m
smaller than in reality and report my incomplete and probably inefficient attempt to construct check
.
clear
rng default
m=4;
n=500;
A_1=betarnd(1,2,m,n);
A_2=betarnd(1,2,m,n);
A_3=betarnd(1,2,m,n);
check=zeros(m,1);
for i=1:m
for j=1:m
for k=1:m
if A_1(i,1)+A_2(j,1)+A_3(k,1)<=quantile(A_1(i,2:end)+A_2(j,2:end)+A_3(k,2:end), 0.95)
check(i)=1;
STOP TO LOOP OVER j AND k, MOVE TO THE NEXT i (INCOMPLETE!)
else
KEEP SEARCHING FOR j,k SUCH THAT THE CONDITION IS SATISFIED (INCOMPLETE!)
end
end
end
end
给出标量 x
和向量 v
,表达式 x< = quantile(v,.95)
可以写为 sum(x> v)<Q
,其中 Q = .95 * numel(v)
*.
Given a scalar x
and a vector v
the expression x <=quantile (v, .95)
can be written as sum( x > v) < Q
where Q = .95 * numel(v)
*.
A_1
也可以在循环之前进行拆分,以避免额外的索引编制.此外,可以移除最内层的循环,从而有利于向量化.
Also A_1
can be splitted before the loop to avoid extra indexing.
Moreover the most inner loop can be removed in favor of vectorization.
Af_1 = A_1(:,1);
Af_2 = A_2(:,1);
Af_3 = A_3(:,1);
As_1 = A_1(:,2:end);
As_2 = A_2(:,2:end);
As_3 = A_3(:,2:end);
Q = .95 * (n -1);
for i=1:m
for j=1:m
if any (sum (Af_1(i) + Af_2(j) + Af_3 > As_1(i,:) + As_2(j,:) + As_3, 2) < Q)
check(i) = 1;
break;
end
end
end
通过重新排列不等式和预计算中涉及的表达式,可以实现更多优化:
More optimization can be achieved by rearranging the expressions involved in the inequality and pre-computation:
lhs = A_3(:,1) - A_3(:,2:end);
lhsi = A_1(:,1) - A_1(:,2:end);
rhsj = A_2(:,2:end) - A_2(:,1);
Q = .95 * (n - 1);
for i=1:m
LHS = lhs + lhsi(i,:);
for j=1:m
if any (sum (LHS > rhsj(j,:), 2) < Q)
check(i) = 1;
break;
end
end
end
- 请注意,由于 quantile 您可能会得到略有不同的结果.
- Note that because of the method that is used in the computation of quantile you may get a slightly different result.