For loop 该随机取样循环是否可以矢量化以进行优化?

For loop 该随机取样循环是否可以矢量化以进行优化?,for-loop,vectorization,octave,permutation,For Loop,Vectorization,Octave,Permutation,我试图在下面的代码中找到如何对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

我试图在下面的代码中找到如何对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
至于文件输入,我有如下内容(只是一个示例,真实文件包含更多数据):

我不知道在向量化语句中可以把增量放在哪里。有可能将其矢量化吗

正如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

错误:randsample:输入k必须是非负整数。无需替换的采样需要k您不能使用
randsample
一次生成多个随机采样(或者从阅读文档中可以看出)。如果
h
足够大,而
perm
n_1
足够小(
sz
>
perm*n_1
),则可以使用
perm*n_1
元素创建随机抽样,然后将其划分为
perm
集合。这可能大致可以,但与您现在所做的不完全相同

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

如果
perm
也很大(如注释所示),但
n_1
仍然很小,您可以使用随机抽样替换来近似此值(使用小
n_1
,在一个集合中重复元素的机会很小):


这并没有回答“我怎样才能向量化”的问题,但是你可能可以通过注意平均值(x_4)=(sum(h)-sum(x_3))/(sz-n_1)来避免一些失败。由于可以在循环外计算sum(h),因此无需创建x_4并计算其平均值,这在sz较大时非常有用。不能使用
randsample
一次生成多个随机抽样。如果
h
足够大,您可以使用
perm*n_1
元素创建随机抽样,然后将其划分为
perm
集合。这可能大致可以,但与您现在所做的不完全相同。如果重复元素的小效果不可接受,则有两种选择。一种是按照您发布的方式进行操作,但随后检查重复并仅“重新滚动”这些元素,重复直到没有重复为止。另一种方法是,对于
j=1:n_1
,从
1:sz+1-j
中生成一列随机数,然后将其视为从先前列中尚未选取的值中进行选择。例如,
i_1=randsample(sz,perm)
i_2=randsample(sz-1,perm)
,然后对于
i_2>=i_1
的行,将i_2增加1。(很抱歉,我的八度音阶太生疏了,无法给出完整的答案。)@GeoffreyBrent:Rerolling是一个不错的选择,但如果
n_1
增加,可能会增加成本。我更喜欢另一个选项,但你又回到了一个循环。:)事实上,对于
n_1>2
它最终是一个双循环,因为避免重复需要对照前面的“j-1”向量检查“i_j”。但是,只要克里斯伦戈你好,谢谢你的回复!我试过运行上面的代码,但它遇到了一个错误。我将更新该问题。@MochammadHusniRizal错误消息解释了问题:默认情况下,randsample samples不替换,但如果perm相对于sz较大,则您尝试采样的值将多于可用于采样的值。您可能需要在randsample调用中设置replacement=true。
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
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));
i_1 = randsample(sz, n_1 * perm, true);