如何在不使用循环的情况下更改矩阵中元素的随机子集的值?

时间:2015-03-16 19:22:22

标签: matlab matrix

我目前正在尝试在一个非常大的矩阵(大约400x300个元素)中选择0的子集并将它们的值更改为1.我能够这样做,但它需要使用一个循环,其中每个实例选择它randperm矢量中的下一个值。换句话说,矩阵中0的50%是随机选择的,一次一个,并改为1:

z=1;
for z=1:(.5*numberofzeroes)
    A(zeroposition(rpnumberofzeroes(z),1),zeroposition(rpnumberofzeroes(z),2))=1;

    z=z+1;
end

其中'A'是矩阵,'zeroposition'是一个2列宽的矩阵,矩阵中的0的位置(如果你喜欢,则为“坐标”),'rpnumberofzeros'是一个randperm向量1到矩阵中的零个数。

例如,对于z = 20,代码可能是这样的:

A(3557,2684)= 1;

...以便A中此位置出现的0现在为1。

它执行此循环数千次,因为.5 * numberofzeroes是一个非常大的数字。这不可避免地需要很长时间,所以我的问题是这可以在不使用循环的情况下完成吗?或者至少在某种程度上减少了处理资源/时间?

正如我所说,唯一需要做的就是完全随机选择50%(或任何比例)的0变为1。

提前感谢您的帮助,如果我能搞清楚的话,请告诉我!我是新来的,如果我做了任何仿制品,请提前道歉。

2 个答案:

答案 0 :(得分:0)

这很容易。我想把你介绍给我的朋友sub2indsub2ind允许您获取矩阵的行和列坐标,并将它们转换为线性列主索引,以便您可以在单个调用中同时访问矩阵中的多个值。因此,您想要的等效代码是:

%// First access the values in rpnumberofzeroes
vals = rpnumberofzeroes(1:0.5*numberofzeroes, :);

%// Now, use the columns of these to determine which rows and columns we want
%// to access A
rows = zeroposition(vals(:,1), 1);
cols = zeroposition(vals(:,2), 2);

%// Get linear indices via sub2ind
ind1 = sub2ind(size(A), rows, cols);

%// Now set these locations to 1
A(ind1) = 1;

第一个语句获取存储在rpnumberofzeroes中的坐标矩阵的前半部分。第一列是行坐标,第二列是列坐标。请注意,在您的代码中,您希望使用zeroposition中的值来访问A中的位置。因此,从rpnumberofzeroes中提取出相应的行和列,以便从zeroposition中找出正确的行和列。完成后,我们希望使用zeroposition中的这些新行和列,并将其编入Asub2ind需要三个输入 - 您尝试访问的矩阵的大小...所以在我们的例子中,A,行坐标和列坐标。输出是一组列主要索引,为每个行和列对计算。

最后一个难题是使用它们来索引A并将位置设置为1.

答案 1 :(得分:0)

这也可以通过线性索引完成:

% find linear position of all zeros in matrix 
ix=find(abs(A)<eps);  
% set one half of those, selected at random, to one.
A(ix(randperm(round(numel(ix)*.5)))=1;