I have a vector n values and i want to split it into groups n groups of 3 adjacent values if it is considered to have a ring topology.
what i am trying to do is this:
vector = [some values];
groups = {};
for i = 1:size(vector)(2)
groups{i} = [vector(mod(i-1, size(vector)(2));
vector(i);
vector(mod(i+1, size(vector)(2))];
endfor
so if n = 10 and i = 1, groups should be [vector(10); vector(1); vector(2)]
it would be pretty straightforward in most programming languages to just use the mod operator, but i am having trouble working out how to do this using matlab as it doesnt use 0 as the initial index of a vector, so if i = 1, then mod(i-1) = 0 which is an illegal index value. Also i = n would be a problem as mod(n, n) = 0.
i have worked out a pretty hack-ish solution in:
vector = [some values];
groups = {};
for i = 1:size(vector)(2)
if i == 1
groups{i} = [vector(size(vector)(2));
vector(1);
vector(2)];
elseif i == size(vector)(2)
groups{i} = [vector(size(vector)(2)-1);
vector(size(vector)(2);
vector(1)];
else
groups{i} = [vector(i-1);
vector(i);
vector(i+1)];
endif
endfor
but it is pretty inelegant and i feel like there should be a better way to do it..
is there some operator that allows you to perform modular arithmetic over vector indexes?
Indeed, the 1-based indexing method of matlab can be quite irritating sometimes...
You can simply add 1 to your 0-based indices, though
n = numel(vector);
for ii = 1:n
idx0 = mod( ii + [-2, 1, 0], n ); % 0-based indices
group{ii} = vector( idx0 + 1 );
end
Now, good Matlab practices are about vectorization, here's one way to vectorize this for-loop
idx0 = mod( bsxfun( @plus, 1:n, [-2;1;0] ), n ); % all indices at once
group = mat2cell( vector( idx0+1 ).', ones(n,1), 3 );
You can lookup mat2cell
in mathworks web site for more information. You can also read about bsxfun here at SO for more examples and information.
PS,
It is best not to use i
as a variable name in Matlab.