Thread Subject: logical indexing question...?

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 14:19:21

Message: 1 of 25

I have the following vector of 1's and 0's

bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];

each time there is a change from 0 to 1 I would like to find the index of the "1"

how would I do this in without a loop?

Subject: logical indexing question...?

From: Arnaud Miege

Date: 19 Nov, 2009 14:46:50

Message: 2 of 25


"happydude " <anonymousse@hotmail.com> wrote in message
news:he3k59$2tn$1@fred.mathworks.com...
>I have the following vector of 1's and 0's
>
> bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
>
> each time there is a change from 0 to 1 I would like to find the index of
> the "1"
>
> how would I do this in without a loop?
>

bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];

idx = find(bits==1);



HTH,



Arnaud

Subject: logical indexing question...?

From: Matt Fig

Date: 19 Nov, 2009 14:52:29

Message: 3 of 25

bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
idx = findstr(bits.',[0 1])+1

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 14:58:03

Message: 4 of 25

ah, thanks...

though i am trying to find the first occurence of the 1 after a switch or change from zero to one...

i.e. i would like the answer to be

ans = [2;5;14;15;];

how might i do this?

thanks again!

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 14:59:20

Message: 5 of 25

matt you are a genius, thank you :)

Subject: logical indexing question...?

From: Jos

Date: 19 Nov, 2009 15:02:03

Message: 6 of 25

"happydude " <anonymousse@hotmail.com> wrote in message <he3k59$2tn$1@fred.mathworks.com>...
> I have the following vector of 1's and 0's
>
> bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
>
> each time there is a change from 0 to 1 I would like to find the index of the "1"
>
> how would I do this in without a loop?

Note that this is not necessarily a "logical indexing question". There is a difference between (0/1) and (false/true), as shown in here
A = [1 2 3] ;
i1 = [1 1 1]
i2 = i1==1
A(i1)
A(i2)
whos

Anyways, try using strfind (which is a little faster than findstr)
bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
strfind(bits.',[0 1])+1 % bits need to be in a row

hth
Jos

Subject: logical indexing question...?

From: Jos

Date: 19 Nov, 2009 15:03:19

Message: 7 of 25

"happydude " <anonymousse@hotmail.com> wrote in message <he3mdr$ofa$1@fred.mathworks.com>...
> ah, thanks...
>
> though i am trying to find the first occurence of the 1 after a switch or change from zero to one...
>
> i.e. i would like the answer to be
>
> ans = [2;5;14;15;];
>
> how might i do this?
>
> thanks again!

15 ??

Subject: logical indexing question...?

From: Arnaud Miege

Date: 19 Nov, 2009 15:05:38

Message: 8 of 25


"happydude " <anonymousse@hotmail.com> wrote in message
news:he3mdr$ofa$1@fred.mathworks.com...
> ah, thanks...
>
> though i am trying to find the first occurence of the 1 after a switch or
> change from zero to one...
>
> i.e. i would like the answer to be
>
> ans = [2;5;14;15;];
>
> how might i do this?
>
> thanks again!
>

Sorry, I didn't read your post propely. I see other people have already
given you a solution.

Arnaud

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 17:06:18

Message: 9 of 25

Sorry Jos, the 15 was a typo.

How could I recreate the bit string using just the vector?

ans = [2;5;14;];

(well actually we also know the length(bits) and that the first bit is 0)

help greatly appreciated !

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 17:09:04

Message: 10 of 25

also what if i have an extremely huge string of bits and i dont know how many times it will swtich back and forth?

Subject: logical indexing question...?

From: Nathan

Date: 19 Nov, 2009 17:33:16

Message: 11 of 25

On Nov 19, 9:06 am, "happydude " <anonymou...@hotmail.com> wrote:
> Sorry Jos, the 15 was a typo.
>
> How could I recreate the bit string using just the vector?
>
> ans = [2;5;14;];
>
> (well actually we also know the length(bits) and that the first bit is 0)
>
> help greatly appreciated !

In my opinion, you can't recreate the bit string using just that
vector, unless your bit string is made under more specific rules.
Possible Solutions of recreation:

bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
bits = [0;1;0;0;1;0;0;0;0;0;0;0;0;1;0;0;];
bits = [0;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;];
bits = [0;1;0;0;1;1;1;1;1;1;1;1;0;1;1;1;];
and any combination thereof.

So, unless you have any specific rules to create your first bit
string, how are you supposed to automatically create it ONLY given the
locations which bits change from 0 to 1 (and not vice-versa)?

-Nathan

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 17:41:20

Message: 12 of 25

lets say we know the first bit string is zero... so the indexes will indicate at what points we change to 1 and back to zero etc

what then? can it be done without looping through the indexes?

Subject: logical indexing question...?

From: Matt Fig

Date: 19 Nov, 2009 17:55:24

Message: 13 of 25

As Nathan correctly points out, the recreated bitstring must be unique (by definition of recreated), but there is no way to create a unique bitstring given its length, the position where the transition occurs and the first bit in the general case. More information is needed to accomplish this.

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 18:38:19

Message: 14 of 25

Oh I see what you mean! My apologies!
what I need is to ALSO find when the original bits change back to Zeros
e.g.
bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
startOnes = strfind(bits.',[0 1])+1;
startZeros = strfind(bits.',[1 0])+1;

% then something like...
bitIndex = sort([startOnes,startZeros]);

% this would give us
bitIndex = [2,4,5,8,14;]

%{
This next bit has got quite confused.. i.e. to recreate the bits I want to do:

between the start of the new/recreated bit string and the 1st index will be "0"
between the 1st Index and the 2nd Index will be "1"
between the 2nd Index and the 3rd Index will be "0"
between the 3rd Index and the 4th Index will be "1"
between the 4th Index and the 5th Index will be "0"
...etc
...etc
until the end of the indexes vector
%}

%I would create a vector

newBits = 1:length(bits);

% then..
%first initializing to zero and then...
%something effectively like....

newbits(x(1,1):x(2,1)) = 1;
newbits(x(3,1):length(bits)) = 1;

% but how to do this for a huge string of bits?

Subject: logical indexing question...?

From: Nathan

Date: 19 Nov, 2009 19:14:00

Message: 15 of 25

On Nov 19, 10:38 am, "happydude " <anonymou...@hotmail.com> wrote:
> Oh I see what you mean! My apologies!
> what I need is to ALSO find when the original bits change back to Zeros
> e.g.  
> bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
> startOnes = strfind(bits.',[0 1])+1;
> startZeros =  strfind(bits.',[1 0])+1;
>
> % then something like...
> bitIndex = sort([startOnes,startZeros]);
>
> % this would give us
> bitIndex = [2,4,5,8,14;]
>
> %{
> This next bit has got quite confused.. i.e. to recreate the bits I want to do:
>
> between the start of the new/recreated bit string and the 1st index will be "0"
> between the 1st Index and the 2nd Index will be "1"
> between the 2nd Index and the 3rd Index will be "0"
> between the 3rd Index and the 4th Index will be "1"
> between the 4th Index and the 5th Index will be "0"
> ...etc
> ...etc
> until the end of the indexes vector
> %}
>
> %I would create a vector
>
> newBits = 1:length(bits);
>
> % then..
> %first initializing to zero and then...
> %something effectively like....
>
> newbits(x(1,1):x(2,1)) = 1;
> newbits(x(3,1):length(bits)) = 1;
>
> % but how to do this for a huge string of bits?

Well, try something like this:

bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
startOnes = strfind(bits.',[0 1])+1;
startZeros = strfind(bits.',[1 0])+1;
bitlen = length(bits);
bitIndex = sort([startOnes,startZeros]);
tmp = diff([1 bitIndex bitlen+1]); %lengths of 0's and 1's
respectively
zidx = ~mod(1:length(tmp),2); %alternate zeros and ones
% 0 1 0 1 0 1 for this case

%Engine: repeat the members of zidx a number of times
%corresponding to the lengths given in tmp
newbits = cell2mat(arrayfun(@(x,y)repmat(x,
1,y),zidx,tmp,'uni',false))';

%%%%%%%%%%%%%%%%%%%%%
isequal(newbits,bits)
ans =
     1


-Nathan

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 19:21:18

Message: 16 of 25

awesome.. this has blown me away!

will take me a little while to test and digest..

thanks again :)

Subject: logical indexing question...?

From: Eli

Date: 19 Nov, 2009 19:23:18

Message: 17 of 25

try this
 answer=[0; abs(diff(bits)==1)]

-Eli
"happydude " <anonymousse@hotmail.com> wrote in message <he3k59$2tn$1@fred.mathworks.com>...
> I have the following vector of 1's and 0's
>
> bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
>
> each time there is a change from 0 to 1 I would like to find the index of the "1"
>
> how would I do this in without a loop?

Subject: logical indexing question...?

From: Eli

Date: 19 Nov, 2009 19:26:23

Message: 18 of 25

or if you want to find both a change to a zero and to a one try this:
 answer=[0; abs(diff(bits))]

"Eli " <elechtma@ryerson.ca> wrote in message <he45v6$c31$1@fred.mathworks.com>...
> try this
> answer=[0; abs(diff(bits)==1)]
>
> -Eli
> "happydude " <anonymousse@hotmail.com> wrote in message <he3k59$2tn$1@fred.mathworks.com>...
> > I have the following vector of 1's and 0's
> >
> > bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
> >
> > each time there is a change from 0 to 1 I would like to find the index of the "1"
> >
> > how would I do this in without a loop?

Subject: logical indexing question...?

From: Matt Fig

Date: 19 Nov, 2009 19:48:05

Message: 19 of 25

Here is another solution which should be much faster.


% Datsa
bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];

% Engine
newbits = zeros(size(bits));
newbits(strfind(bits.',[0 1])+1) = 1;
newbits(strfind(bits.',[1 0])+1) = -1;
newbits = cumsum(newbits); % Recreated vector.



Note that the strfind calls can be taken out of the parenthesis and assigned to a variable if needed.

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 20:28:01

Message: 20 of 25

Matt, how about if you:
clear bits;

before trying to recreate it?
i.e. you can "transfer" size and intervals etc, but not the actual bit string

would it possible without loops? or arrayfun (as in Nathan's solution)? (arrayfun uses loops right? so i'm guessing this would be quite slow for a large set?)

Subject: logical indexing question...?

From: Nathan

Date: 19 Nov, 2009 20:44:48

Message: 21 of 25

On Nov 19, 12:28 pm, "happydude " <anonymou...@hotmail.com> wrote:
> Matt, how about if you:
> clear bits;
>
> before trying to recreate it?
> i.e. you can "transfer" size and intervals etc, but not the actual bit string
>
> would it possible without loops? or arrayfun (as in Nathan's solution)? (arrayfun uses loops right? so i'm guessing this would be quite slow for a large set?)

Matt's works wonderfully and doesn't use bits other than for the
length and locations, as suggested.
It is loads faster than my method.

Is this more clear?

bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
%Values allowed to save
len = length(bits); %length
idx1 = strfind(bits.',[0 1])+1; %0 to 1
idx2 = strfind(bits.',[1 0])+1; %1 to 0
%clear bits to show method doesn't rely on it
clear bits
% Engine
newbits = zeros(len,1);
newbits(idx1) = 1;
newbits(idx2) = -1;
newbits = cumsum(newbits); % Recreated vector.

%Show that bits and newbits are the same
bits = [0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;];
isequal(newbits,bits)
%%%%%%%%%%%%%%%%%%%%%%%
ans =
     1


-Nathan

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 20:46:40

Message: 22 of 25

let me rephrase, so if you had

the total length of "bits"
the length of each bit string
the index of changes from zero to one and back to zero

we don't know the original bit string, how do you recreate the bits with no loops?

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 20:52:04

Message: 23 of 25

you replied so fast you beat my follow-up post :)

let me check it out... not nearly as fast as you guys!

Subject: logical indexing question...?

From: Nathan

Date: 19 Nov, 2009 20:54:06

Message: 24 of 25

On Nov 19, 12:46 pm, "happydude " <anonymou...@hotmail.com> wrote:
> let me rephrase, so if you had
>
> the total length of "bits"
> the length of each bit string
> the index of changes from zero to one and back to zero
>
> we don't know the original bit string, how do you recreate the bits with no loops?

...
Okay. I'll assume your bits always starts with 0 and idx is your array
if index changes.
idx1 = idx(1:2:end) %0 to 1 bit changes
idx2 = idx(2:2:end) %1 to 0 bit changes
let len be the total length of bits

AGAIN:
newbits = zeros(len,1);
newbits(idx1) = 1;
newbits(idx2) = -1;
newbits = cumsum(newbits); % Recreated vector.

-Nathan

Subject: logical indexing question...?

From: happydude

Date: 19 Nov, 2009 21:05:23

Message: 25 of 25

this seriously helped me out a lot... How did do it so quick?

i was really stuck and now it seems so simple thanks to you.....

Matt, Nathan you guys are incredible!

Tags for this Thread

Everyone's Tags:

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Tag Activity for This Thread
Tag Applied By Date/Time
logical indexin... happydude 19 Nov, 2009 09:24:23
rssFeed for this Thread

Contact us at files@mathworks.com