fast and beautiful way to convert vector ranges to indexes

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

 채택된 답변

Matt J
Matt J 2014년 7월 23일
c=cumsum(v2);
v3=zeros(1,c(end));
v3([1,c(1:end-1)])=1;
v3=cumsum(v3);
v3(end)=[],

댓글 수: 2

Vincent
Vincent 2014년 7월 23일
편집: Vincent 2014년 7월 23일
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 2014년 7월 23일
편집: Matt J 2014년 7월 23일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (4개)

Andrei Bobrov
Andrei Bobrov 2014년 7월 23일
v2 = [5; 2; 3];
ii = cumsum(v2);
v3 = zeros(ii(end),1);
v3( ii - v2 + 1) = 1;
v3 = cumsum(v3);

댓글 수: 2

this seems pretty similar to Matt J's solution to me, right?

댓글을 달려면 로그인하십시오.

Azzi Abdelmalek
Azzi Abdelmalek 2014년 7월 23일
v2 = [5; 2; 3];
v3=cell2mat(arrayfun(@(x) repmat(x,1,v2(x)),1:numel(v2),'un',0))

댓글 수: 2

not really loopless...
this is at least a single-line solution. But Matt is right - thanks for your answer anyway!

댓글을 달려면 로그인하십시오.

Matt J
Matt J 2014년 7월 23일
Here's a 1-liner,
[~,v3]=histc(1:sum(v2),[1;cumsum(v2(:))+1])

댓글 수: 2

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])
Oh I would never have thought about histc! Nice idea! Thanks

댓글을 달려면 로그인하십시오.

Jan
Jan 2014년 7월 23일
v2 = [5; 2; 3];
v3 = RunLength(1:length(v2), v2);

댓글 수: 1

I just looked up your function - looks pretty nice! Unfortunately I have to stick on built-in functions in my case :-/

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Mathematics에 대해 자세히 알아보기

제품

태그

질문:

2014년 7월 23일

댓글:

2014년 7월 24일

Community Treasure Hunt

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

Start Hunting!

Translated by