Clear Filters
Clear Filters

choose one out of every 8 elements randomly

3 views (last 30 days)
I have a 1xm matrix and I want to choose one out of every 8 elements randomly, I can think of ways using for loops but I was hoping for a solution without for loops and efficient in terms of speed. Thanks

Accepted Answer

goerk
goerk on 8 Jan 2016
Edited: goerk on 8 Jan 2016
m = 21;
A = (1:m)+0.314;
nof8 = ceil(m/8);
randSelect = randi([1 8],1,nof8);
inds = randSelect+(0:nof8-1)*8;
% if m is not a multiple of 8 the last samples must get special treatment
% the simplest solution is to limit the indices in inds to the m
inds(end)=min(inds(end),m);
% but this leads to a non-uniform distribution for the last selection.
selectedElements = A(inds)
A solution with an uniform distribution for all cases was suggested from Guillaume:
randselect = randi(8, 1, floor(numel(A)/8));
if mod(numel(A), 8) > 0
randselect = [randselect, randi(mod(numel(A), 8))];
end
selectedvalues = A(randselect + (0:ceil(numel(A)/8)-1)*8)
  11 Comments
goerk
goerk on 12 Jan 2016
Select multiple (unique) Samples:
m = 21;
A = (1:m)+0.314;
nof8 = floor(m/8); %floor-> if m ~= x*8 ignore last samples
nofSamples = 2;
randSelect = zeros(nofSamples,nof8);
for i=1:nof8
randSelect(:,i)= randperm(8,nofSamples);
end
inds = randSelect+repmat((0:nof8-1)*8,nofSamples,1);
selectedElements = A(inds)
Guillaume
Guillaume on 12 Jan 2016
Edited: Guillaume on 12 Jan 2016
Since the number of elements is always multiple of 8, this is a case where using reshape is a lot more elegant.
A = 1:104;
nofsamples = 3;
A8 = reshape(A, 8, []);
selectedelements = A8(sub2ind(size(A8), randperm(8, nofsamples), 1:size(m8, 2)))
%if required as a vector:
selectedelements = selectedelements(:)

Sign in to comment.

More Answers (2)

Guillaume
Guillaume on 8 Jan 2016
One possible way:
m = 1:104; %input
assert(mod(numel(m), 8) == 0, 'the number of elements in m must be a multiple of 8');
m8 = reshape(m, 8, []);
m8(sub2ind(size(m8), randi(8, 1, size(m8, 2)), 1:size(m8, 2)))

Nobel Mondal
Nobel Mondal on 8 Jan 2016
m = 100;
spacedIds = [0:8:m];
rands = randi(8, 1, size(spacedIds,2)-1);
randIds = spacedIds(1:end-1)+ rands;
% check if m is not a multiple of 8
% add another number from the remaining tail-section
if ~(spacedIds(end) == m)
randIds(end+1) = spacedIds(end) + randi(m-spacedIds(end), 1,1);
end

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!