Asked by Russell Evans
on 22 May 2018

If I have a vector [636 637 638 24639 24640 48640 48641 48642 48643], what code can I write to pull the first element in each consecutive series of elements within the vector. In the above example, the elements I would want are [636 24639 48640]. The elements are not always the first, fourth, and sixth indices. But rather, I can produce a vector that contains elements that can be consecutive at times, yet I only want the first element in the sequence of consecutive elements.

Thank you

Answer by Fangjun Jiang
on 22 May 2018

Something like this?

a=[636 637 638 24639 24640 48640 48641 48642 48643];

b=[0 a];

c=diff(b);

index=c>1;

out=a(index);

Guillaume
on 23 May 2018

In any case, it's easily fixed by changing

index = c>1;

into

index = c ~= 1;

Assuming the sequences are monotonically increasing.

John BG
on 23 May 2018

Jan Simon, the 'original example' is only a sample.

It's not clear from the question so far whether negative values should be considered or not.

What do we do when we don't know the sign of a variable?

I don't know you but better safe than sorry, I just consider such possibility.

Why don't you ask Russel, don't you the MVPs have access to the provided email addresses when people create accounts in this forum?

or is it just the Staff?

The elements are not always the first, fourth, and sixth indices.

But rather, I can produce a vector that contains elements that can be consecutive at times,

You see, there are more samples to process.

why would anyone consider coding a procedure that has to run on 1 and only 1 specific particular vector?

John BG

Jan
on 23 May 2018

The author will ask by himself, if he needs modifications. It is his thread. Speculations, that he wants beside the shown growing sequences of positive numbers also shrinking sequences of negative numbers is confusing only, because there is no evidence for this. Why not growing sequences of negative numbers, or complex values, or steps apart from 1.0, or quaternions, or characters insensitive for case?

Of course the editors do not get access to the contact information of other members. And even if they do, they would not be so impolite to push authors of questions personally.

Together with Guillaume's addition, Fangjun's solution is neat and powerful:

out = a(diff([0 a]) ~= 1)

Or to catch shrinking sequences also:

out = a(abs(diff([0 a])) ~= 1)

Logical indexing is nicer and more efficient than a find.

Sign in to comment.

Answer by John BG
on 22 May 2018

Edited by John BG
on 22 May 2018

Hi Russel

1.- generating data

N=5

a=randi([-1000 1000],1,N);

b=2*(randi([0 1],1,N)-.5);

c=randi([5 15],1,N);

L=[]

for k=1:1:N

L=[L repmat(a(k),1,c(k))+[0:b(k):b(k)*c(k)-b(k)]];

end

2.-

Let be for instance

L

L =

Columns 1 through 10

-492 -493 -494 -495 -496 -497 -498 -499 -500 -501

Columns 11 through 20

-502 -503 -504 -505 629 628 627 626 625 624

Columns 21 through 30

623 622 621 620 619 -513 -512 -511 -510 -509

Columns 31 through 40

-508 -507 -506 -505 -504 -503 859 858 857 856

Columns 41 through 50

855 854 853 852 851 850 849 848 847 846

Columns 51 through 59

845 -300 -301 -302 -303 -304 -305 -306 -307

3.-

L2=abs(abs(diff(L))-1);

S=[L(1) L(find(L2>0)+1)]

S =

-492 629 -513 859 -300

If instead of

a=randi([-1000 1000],1,N);

the input sequence should positive only, then replace with

a=randi([1 1000],1,N);

It also works with positive integers input only.

.

Comment: these 2 simple lines work for positive or negative integers, and for ascending +1 or descending -1 bursts.

.

Russel

if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?

To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link

thanks in advance for time and attention

John BG

Paolo
on 23 May 2018

Hi John,

I tried your code with input

L = [637 638 0 1 0 1 637 638];

And the output was :

637 0 637

And I tried with:

L = [637 638 637 638];

And the output was:

637

Is this expected?

John BG
on 23 May 2018

this is the same as with input

0 1 0 1

your code, that you remove,don't know why, it worked ok, does the same: it only takes the first value as long as consecutive variations are +1 -1

It makes sense because it's about simplifying the input sequence. It's not clear from the single input example supplied, but it's obvious that the supplied sample is not the only vector to process. Why would be coding anything anyway if it's not to process more samples that have not been shown in the question?

Paolo, you already mentioned that your code does the same, why don't you put back your code?

Let Russel Evans decide.

Regards

John BG

Paolo
on 23 May 2018

John,

The reason I removed my solution:

A = [636 -637 -638 24639 24640 48640 48641 48642 -48643];

out=[A(1) A(find((diff(A)~=1)&(diff(A)~=-1)&(diff(A)~=0))+1)];

is because it does not provide a complete solution to the problem. As you correctly pointed out, it does not deal successfully with variations that differ from +1 and -1. I agree with you that the solution should successfully deal with any sequence, as you pointed out in the comment to Fangjun's answer. However, none of the solutions provided so far can do that.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.