Generating an array with a series of start and end points

  • Follow


My question is as follows:

I have two arrays with the same length, one contains the start points, and the other contains the end points. I'd like to "decompress" the two array, to get the third array that contains all the numbers between the start points and the end points. Is there a more efficient way to do this than looping through all the start and end points?

e.g.
start = [2 1 4 7];
end = [5 4 6 8];

=> results = [ 2:5  1:4  4:6  7:8];

Note the order of the numbers have to be preserved in the results, so the numbers between the first start-end pair appear first, and those of the second group appear right after the first one, and so on.

Any tips will be greatly appreciated!
0
Reply Kuei 1/21/2010 9:02:04 PM

On Jan 21, 1:02=A0pm, "Kuei-Chun Hsu" <b92902...@ntu.edu.tw> wrote:
> My question is as follows:
>
> I have two arrays with the same length, one contains the start points, an=
d the other contains the end points. I'd like to "decompress" the two array=
, to get the third array that contains all the numbers between the start po=
ints and the end points. Is there a more efficient way to do this than loop=
ing through all the start and end points?
>
> e.g.
> start =3D [2 1 4 7];
> end =3D [5 4 6 8];
>
> =3D> results =3D [ 2:5 =A01:4 =A04:6 =A07:8];
>
> Note the order of the numbers have to be preserved in the results, so the=
 numbers between the first start-end pair appear first, and those of the se=
cond group appear right after the first one, and so on.
>
> Any tips will be greatly appreciated!

Do you want your "results" variable to be a cell array, where each
element consists of those smaller consecutive arrays, or do you want a
matrix in which these values are one after another?

Either way:
start1 =3D [2 1 4 7];
end1 =3D [5 4 6 8]; %end is a matlab special word
resultC =3D arrayfun(@(x,y)(x:y),start1,end1,'uni',false);
resultM =3D cell2mat(arrayfun(@(x,y)(x:y),start1,end1,'uni',false));
%%%%%%%%%%%%
resultC =3D
    [1x4 double]    [1x4 double]    [1x3 double]    [1x2 double]
resultM =3D
     2     3     4     5     1     2     3     4     4     5     6
7     8

-Nathan


0
Reply Nathan 1/21/2010 9:08:16 PM


Thank you so much Natha! I need a row vector that contains all the numbers (resultM). I've never known Matlab have functions like those, that could avoid lots of loops in my program. (Though I heard there are performance issues, it's still very cool!!)

-Kuei-Chun

Nathan <ngreco32@gmail.com> wrote in message <bb5492fc-b9e3-452f-8d48-98fe3dae1011@a15g2000yqm.googlegroups.com>...
> On Jan 21, 1:02 pm, "Kuei-Chun Hsu" <b92902...@ntu.edu.tw> wrote:
> > My question is as follows:
> >
> > I have two arrays with the same length, one contains the start points, and the other contains the end points. I'd like to "decompress" the two array, to get the third array that contains all the numbers between the start points and the end points. Is there a more efficient way to do this than looping through all the start and end points?
> >
> > e.g.
> > start = [2 1 4 7];
> > end = [5 4 6 8];
> >
> > => results = [ 2:5  1:4  4:6  7:8];
> >
> > Note the order of the numbers have to be preserved in the results, so the numbers between the first start-end pair appear first, and those of the second group appear right after the first one, and so on.
> >
> > Any tips will be greatly appreciated!
> 
> Do you want your "results" variable to be a cell array, where each
> element consists of those smaller consecutive arrays, or do you want a
> matrix in which these values are one after another?
> 
> Either way:
> start1 = [2 1 4 7];
> end1 = [5 4 6 8]; %end is a matlab special word
> resultC = arrayfun(@(x,y)(x:y),start1,end1,'uni',false);
> resultM = cell2mat(arrayfun(@(x,y)(x:y),start1,end1,'uni',false));
> %%%%%%%%%%%%
> resultC =
>     [1x4 double]    [1x4 double]    [1x3 double]    [1x2 double]
> resultM =
>      2     3     4     5     1     2     3     4     4     5     6
> 7     8
> 
> -Nathan
> 
0
Reply Kuei 1/21/2010 9:28:04 PM

"Kuei-Chun Hsu" <b92902123@ntu.edu.tw> wrote in message <hjafcb$jsm$1@fred.mathworks.com>...
> My question is as follows:
> 
> I have two arrays with the same length, one contains the start points, and the other contains the end points. I'd like to "decompress" the two array, to get the third array that contains all the numbers between the start points and the end points. Is there a more efficient way to do this than looping through all the start and end points?
> 
> e.g.
> start = [2 1 4 7];
> end = [5 4 6 8];
> 
> => results = [ 2:5  1:4  4:6  7:8];
> 
> Note the order of the numbers have to be preserved in the results, so the numbers between the first start-end pair appear first, and those of the second group appear right after the first one, and so on.
> 
> Any tips will be greatly appreciated!

Although I recommend the arrayfun approach proposed by Nathan, here is an old-school-matlab one-liner:

startIDX = [2 1 4 7]
endIDX = [5 4 6 8] ;
[results,dummy] = find(cumsum(full(sparse(startIDX,1:numel(startIDX),1,max(endIDX)+1,numel(startIDX)) + sparse(endIDX+1,1:numel(startIDX),-1,max(endIDX)+1,numel(startIDX))))) ; 

Jos
0
Reply Jos 1/22/2010 9:42:05 AM

> "Kuei-Chun Hsu"
> > My question is as follows:
> > 
> > I have two arrays with the same length, one contains the start points, and the other 
> > contains the end points. I'd like to "decompress" the two array, to get the third array that
> > contains all the numbers between the start points and the end points. Is there a more
> > efficient way to do this than looping through all the start and end points?

A for loop should be faster. So if you mean something faster go for the loop.

(if you mean something evil go for the eval: http://www.mathworks.com/matlabcentral/newsreader/view_thread/270573#709902. 
In this post other alternatives are discussed and Jos's as well. It all began there...)

eval(fliplr(')''gelO .live m''''I''(psid')) 
0
Reply Oleg 1/22/2010 9:52:05 AM

4 Replies
189 Views

(page loaded in 0.073 seconds)

Similiar Articles:













7/24/2012 8:20:41 AM


Reply: