这个随机采样循环可以矢量化以进行优化吗?

Can this random sampling loop be vectorised for optimisation?

我试图在下面的代码中找到如何向量化 FOR 循环的方法:

h=load('water-column');                 % load file 
perm=5;                         % make 10000 permutation
n_1=5;                            % number of random sample
dm_ale=zeros(1,perm);               % create a vector 
sz=length(h);                     % count size of matrix data    
for k=1:perm                      % making loop for the permutation
    i_1=randsample(sz,n_1);      
    x_3=h(i_1);            
    x_4=h(setdiff(1:sz,i_1));    
    dm_ale(k)=abs(mean(x_3)-mean(x_4)); % calculate difference of mean for each permutation
end

关于文件输入,我有这样的东西(只是一个例子,真正的文件包含更多数据):

   3792.615000000000
   3792.625000000000
   3792.634000000000
   3792.640000000000
   3792.647000000000
   3792.654000000000
   3792.662000000000
   3792.668000000000
   3792.673000000000

我想不出可以将增量放在向量化语句中的什么位置。是否可以对其进行矢量化?

由于 Cris Luengo(抱歉,我不知道如何标记用户)提出的代码,我遇到了一个错误:

error: randsample: The input k must be a non-negative integer. Sampling without replacement needs k <= n.
error: called from
    randsample at line 46 column 5
    random_sampling at line 8 column 5

其中 random_sampling 是代码的名称。

最初我需要 perm=10000(进行稳健的随机抽样测试)和 n_1=600(需要人口数量以便我的测试可以进行)。即使我遵守条件,上面的代码似乎也不起作用:n_1^2 << perm。 我假设错误是由于 n_1 引起的,它仍然与 perm 相关的足够大。 还有别的线索吗?我正在考虑增加 perm.

您不能使用 randsample 一次生成多个随机样本(或者从阅读文档来看似乎如此)。如果 h 足够大,并且 permn_1 足够小 (sz >> perm*n_1),则可以使用 [= 创建随机抽样17=] 个元素,然后将其分成 perm 个集合。这可能大致没问题,但与您现在所做的并不完全相同。

您的代码将如下所示(使用 Geoffrey Brent 建议的简化):

h = load('col-deau');
perm = 5;
n_1 = 5;
sz = numel(h);  % numel is always better than length if you use one index h(i_1) rather than two h(i_1,1)
sum_h = sum(h)
i_1 = randsample(sz, n_1 * perm);
i_1 = reshape(i_1, n_1, perm);
x_3 = h(i_1);                    % x_3 has the same size as i_1
x_3 = sum(x_3, 1);               % sum over columns, x_3 has perm elements now
x_4 = sum_h - x_3;
dm_ale = abs(x_3 / n_1 - x_4 / (sz-n_1));

如果 perm 也很大(如评论中所示),但 n_1 仍然很小,您可以使用带替换的随机抽样(小 n_1 , 你在一组中有重复元素的机会很小):

i_1 = randsample(sz, n_1 * perm, true);