1

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?

guskenny83
  • 1,321
  • 14
  • 27

1 Answers1

3

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 , 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 here at SO for more examples and information.


PS,
It is best not to use i as a variable name in Matlab.

Community
  • 1
  • 1
Shai
  • 111,146
  • 38
  • 238
  • 371
  • 1
    Smart solution with that `bsxfun`! – Divakar Sep 04 '14 at 05:38
  • thanks a lot for that, it works for what i need, and i'm pretty sure that i understand what is going on, i havent had a lot of experience with matlab up until now so it looks like i have a lot to learn. If you aren't too busy, can you give a brief description of what is happening in that vectorisation? If not i can do some reading myself. Thanks a lot for your help at any rate. – guskenny83 Sep 04 '14 at 05:43
  • actually, now that i look closely, this solution doesnt quite give me what i am after; groups{1} of the solution you provided gives {vector(1); vector(2); vector(3)} whereas it should give {vector(n); vector(1); vector(2)}. is achieving that as simple as changing the [-1 0 1] part to [-2 1 0]? – guskenny83 Sep 04 '14 at 05:57
  • changed [-1 0 1] to [-2 -1 0] and it worked fine, thanks again – guskenny83 Sep 04 '14 at 05:59
  • @guskenny83 I suppose it is indeed as easy as the change you proposed. – Shai Sep 04 '14 at 05:59