fast and beautiful way to convert vector ranges to indexes

1 vue (au cours des 30 derniers jours)
Vincent
Vincent le 23 Juil 2014
Commenté : Vincent le 24 Juil 2014
Hi there,
my question could easily be solved with a simple loop but I'm curious if there is a nice genuine matlab way of doing this: I have a vector "v1" containing 10 entries. First 5 belong together, next 2 belong together and the last 3 again (somehow). So I got a vector "v2" with
v2 = [5; 2; 3];
I want now something like
v3 = [1 1 1 1 1 2 2 3 3 3];
So I could access my v1 vector with:
v1(v3==1);
(Background for the question are different colors for each group with the plot-command.)
Thanks already in advance - I'm sure Matlab holds a nice and short way of doing this :-)
Vincent

Réponse acceptée

Matt J
Matt J le 23 Juil 2014
c=cumsum(v2);
v3=zeros(1,c(end));
v3([1,c(1:end-1)])=1;
v3=cumsum(v3);
v3(end)=[],
  2 commentaires
Vincent
Vincent le 23 Juil 2014
Modifié(e) : Vincent le 23 Juil 2014
Nice, except for one little mistake (line 3, move the first "1" out of the square brackets). Also the last line didn't seem to be necessary as we took "end-1" beforehand I guess…
Unfortunately not a single line of code, but I guess I've been looking for something like "cumsum". Still odd, that there's no more condensed way in Matlab to achieve this…
Matt J
Matt J le 23 Juil 2014
Modifié(e) : Matt J le 23 Juil 2014
Here's a 2-line version
v3(cumsum(v2)+1)=1;
v3=cumsum(v3(1:end-1))+1
but the number of lines is inconsequential anyway. You can always reduce code to 1 line by wrapping it in your own mfile.

Connectez-vous pour commenter.

Plus de réponses (4)

Andrei Bobrov
Andrei Bobrov le 23 Juil 2014
v2 = [5; 2; 3];
ii = cumsum(v2);
v3 = zeros(ii(end),1);
v3( ii - v2 + 1) = 1;
v3 = cumsum(v3);
  2 commentaires
Vincent
Vincent le 23 Juil 2014
this seems pretty similar to Matt J's solution to me, right?
Andrei Bobrov
Andrei Bobrov le 23 Juil 2014
of course

Connectez-vous pour commenter.


Azzi Abdelmalek
Azzi Abdelmalek le 23 Juil 2014
v2 = [5; 2; 3];
v3=cell2mat(arrayfun(@(x) repmat(x,1,v2(x)),1:numel(v2),'un',0))
  2 commentaires
Matt J
Matt J le 23 Juil 2014
not really loopless...
Vincent
Vincent le 23 Juil 2014
this is at least a single-line solution. But Matt is right - thanks for your answer anyway!

Connectez-vous pour commenter.


Matt J
Matt J le 23 Juil 2014
Here's a 1-liner,
[~,v3]=histc(1:sum(v2),[1;cumsum(v2(:))+1])
  2 commentaires
Matt J
Matt J le 23 Juil 2014
Although, to avoid summing v2 twice, it is best to break it into 2 lines
c=cumsum(v2(:));
[~,v3]=histc(1:c(end),[1;c+1])
Vincent
Vincent le 24 Juil 2014
Oh I would never have thought about histc! Nice idea! Thanks

Connectez-vous pour commenter.


Jan
Jan le 23 Juil 2014
  1 commentaire
Vincent
Vincent le 24 Juil 2014
I just looked up your function - looks pretty nice! Unfortunately I have to stick on built-in functions in my case :-/

Connectez-vous pour commenter.

Catégories

En savoir plus sur Matrix Indexing dans Help Center et File Exchange

Tags

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by