**You are now following this question**

- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.

# Find sorrunding elements and element from an array

1 view (last 30 days)

Show older comments

I have an array

y = [

0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0]

where Index 7,41,75 are the locations where 1 is found .

My requirement is

- create a block around true(1) with a size of 5
- get the indices like 5,6,7,8,9 and data 0 0 1 0 0

##### 25 Comments

Walter Roberson
on 26 Oct 2020

What shoud the output be if you have nearby pixels? For example

y = [

0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ...

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

0 0 0 0 0 0 0 0 0]

Jogger
on 26 Oct 2020

- include the nearby pixel as well in the block of 5 elements
- if first pixel 1 then include next 4 elements
- if end pixel 1 then include previous 4 elements

Walter Roberson
on 26 Oct 2020

So to confirm, you would want [0 0 1 0 1] indices [5 6 7 8 9] and [1 0 1 0 0] indices [7 8 9 10 11] ?

Anyhow, what is your question?

Jogger
on 26 Oct 2020

So to confirm, you would want [0 0 1 0 1] indices [5 6 7 8 9] and [1 0 1 0 0] indices [7 8 9 10 11] ?

[0 0 1 0 1]

5 6 7 8 9 ==> Block 1

[1 0 1 0 0]

[7 8 9 10 11] ==> Block 2

we don't need block2 if the indices is in Block 1 . Index repeatation will consume memory and processing time increases.

And more so first indices and last indices should be 1st Indcie + 4(next ) & Last indice - 4 (previous)

Walter Roberson
on 27 Oct 2020

we don't need block2 if the indices is in Block 1

So you want a single combined output that is longer, block1 = [0 0 1 0 1 0 0] indices [5 6 7 8 9 10 11] ?

Walter Roberson
on 27 Oct 2020

You appear to be doing a homework assignment. When I read the homework assignment, I am left certain that you are intended to always produce blocks of 5. Index duplication and memory consumption is not a primary concern: the block of 5 is imposed by the question.

As such, there is a much easier solution to finding the indices. Hint: find() and min() and max() . You can calculate the starting and ending indices in vectorized form.

Once you have vectors of the starting and ending indices, you can loop or arrayfun to extract the contents.

Jogger
on 27 Oct 2020

You have a mis understing ! The requirement is

- Block is needed as an input to process the polynomial vector.
- movmax makes the poly bit as 1 .. This is incorrect since it over write poly error information
- A block can start from 1 bit as 1 and trail bit either 0/1 .
- In case of variable block/s, you know the CRC points in a data set then why re-run same data. This is using more memory (buffer) and processs time. I don't understand why this should not be concern

It will be a help to have a very simple code/algorithm if you can share just to have as a starting point,

I shared a sample code below, can you please add more robust logic to get desired results.

Thank you!

Walter Roberson
on 27 Oct 2020

start = max(1, position-2);

stop = start + 4;

Now do the fix-up for end of buffer.

Jogger
on 27 Oct 2020

For end bit , I think padding is needed

For example

y1 = [1 0 0 0 0 ]

y2 = [0 1 0 0 0 ]

y3 = [0 0 1 0 0 ] & so on

to accomadate the block size fit the fixed polynomial size

Walter Roberson
on 27 Oct 2020

Jogger
on 27 Oct 2020

OK, we can do the reverse count from end and put the previous bit in to the array

y = [ 0 0 0 0 0 0 0 0 1 0]

position is 9 then ?

I expect the result should be

blockBits(:,:,1) = [1,0,0,0,0]

blockindcs(:,:,1) = [9, 10, 8,7,6]

Walter Roberson
on 27 Oct 2020

No need to do reverse indices.

Think about the code I posted:

start = max(1, position-2);

stop = start + 4;

We started at some unknown position. We go blocksize/2 towards an edge that is of interest to us, which would normally get us the location of the edge. But we check whether taking that step would have positioned that tentative edge beyond the actual edge, and if it did then we substitute the coordinate of the actual edge instead. Then we take that (possibly substituted) coordinate and say that the other end of the block is the blocksize towards the other edge.

It is trivial to extend this to do the same logic against the other edge, detecting if we have passed the actual edge and if so moving the boundary to the actual edge and saying that the other end of the block is blocksize towards the front.

Jogger
on 27 Oct 2020

No no.. this is wrong explanation for edge detection

As per your logic ,

start = max(1, position-2);

stop = start + 4;

we don't know what is the error value at start but position define error.If you train

a edge detection polynomial with leading edge with non error bit. Then the logic won't make

sense

Below is an example

Leading bit can be 0.

a = [ 1 0 0 0 1 ]; sys = idpoly(a)

sys =

Discrete-time AR model: A(z)y(t) = e(t)

A(z) = 1 + z^-4

Sample time: unspecified

Parameterization:

Polynomial orders: na=4

Number of free coefficients: 4

Use "polydata", "getpvec", "getcov" for parameters and their uncertainties.

Status:

Created by direct construction or transformation. Not estimated.

K>> a = [ 0 0 0 0 1 ]; sys = idpoly(a)

Error using idpoly (line 384)

The leading coefficient of the "A" polynomial must be 1.

But for a polynomial leading position must 1 and tail bits can be 0/1. What if block started with 0. So edge detection will not proceed at the initial state.

For the end block , it is Ok to process 1-4 to additional bits to go pass the edge unless we have a conving logic

as I proposed

- bit reverse
- padd to sufice the block which is a polynomial
- short polynomial

for a block to process for edge detection. The problem with Short polynomial size than a block size then we have size error...

Please have re look into below code and suggest solution for ( I prefer to have offset elements to have 0 filled , then we don't alter edge detection error bit and it will be safe)

if bit_position>= (siz_y-blksize)

blockBits(:,:,i) = y(bit_position:1:siz_y);

blockindcs(:,:,i) = (bit_position:1:siz_y);

end

Current implementation with a bad size for end block

y = [

0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...

0 0 0 0 0 0 0 1 0]

siz_y = size(y,2);

[Val,idx] = find(y>0);

blksize = 5;

blockBits = zeros(1,blksize,size(idx,2));

blockindcs = zeros(1,blksize,size(idx,2));

statelock = 0;

yMax = movmax(y, blksize);

props = regionprops(yMax > 0, 'PixelIdxList'); % Requires the Image Processing Toolbox.

for i = 1:size(idx,2)

bit_position = idx(i);

% blockBits(:,:,i) = y(props(i).PixelIdxList);

% blockindcs(:,:,i) = props(i).PixelIdxList;

% start = max(1, bit_position-2)

% stop = start + 4

% blockBits(:,:,i) = y(start:1:stop)

% blockindcs(:,:,i) = (start:1:stop)

if (bit_position>blksize) && bit_position< (siz_y-blksize)

blockBits(:,:,i) = y(bit_position:1:bit_position+4);

blockindcs(:,:,i) = bit_position:1:bit_position+4;

end

if bit_position<=blksize

blockBits(:,:,i) = y(bit_position:1:bit_position+4);

blockindcs(:,:,i) = bit_position:1:bit_position+4;

end

if bit_position>= (siz_y-blksize)

% bit_position = 100,

% siz_y = 101

% offset = 3

% Fill blockindcs offset & substitute with 0's

% 97 98 99 100 101

% blockindcs = 100 101 99 98 97

% blockBits = 1 0 0 0 0

blockBits(:,:,i) = y(bit_position:1:siz_y); % fill offset with 0's

blockindcs(:,:,i) = (bit_position:1:siz_y);

end

end

Walter Roberson
on 27 Oct 2020

All that stuff is irrelevant. You gave the definition at https://www.mathworks.com/matlabcentral/answers/626663-find-sorrunding-elements-and-element-from-a-array#comment_1087903

Though you did omit the definition for the case [0 1 x x x]

Adam Danz
on 27 Oct 2020

Trying to catch up, here.

What doesn't work from this approach?

% Create example input with true at 7,9,41,75

y = false(1,101);

y([7,9,41,75]) = true

y = 1x101 logical array

0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0

% Pad 2 false values to the beginning and end

ypad = [false(1,2), y, false(1,2)];

% Find locations of True

I = find(ypad(:)')

I = 1×4

9 11 43 77

●

% Remove any values of I closer than 2-units

I([false,diff(I)<=2]) = []

I = 1×3

9 43 77

●

% Isolate each true-value +/-2 to the right/left

% and remove the effect of padding

A = find(ypad(:)) + (-4:0)

A = 4×5

5 6 7 8 9
7 8 9 10 11
39 40 41 42 43
73 74 75 76 77

●

B = ypad(A+2)

B = 4x5 logical array

0 0 1 0 1
1 0 1 0 0
0 0 1 0 0
0 0 1 0 0

Jogger
on 27 Oct 2020

Hi Adam,

If we see the B out put we have 4 rows and 5 column.

Each row is a polynomial with a size of 5 ( column). I consider it as block size ( so 4 blocks with polynomial size of 5)

What is not OK in the output B is , starting element is NOT 1 and this will lead to coefficient of the polynomial must be 1 error )

Note: Important point is , we have to keep the polynomial size same (so that I don't have to change the degree of polynomial ) and run the polynomial data having error bits.

So we have to re work the logic !

Thank you

Jogger
on 27 Oct 2020

Please see the figure,

C - represent , no data & it has a dimension of 3x5 . We dont have to run a error polynomial coeff , so removing.I am looking this solution.

For indices location

A to A' is improvement

A to C' is final expectation

For logical values

B to B' is improvement

B to C' is final expectation

Adam Danz
on 27 Oct 2020

Jogger
on 28 Oct 2020

You have A_idx = [5 6 7 8 9] but expectation is A'_idx = [7 8 9 6 5]

You have A_idx = [0 0 1 0 1] but expectation is A'_bits = [1 0 1 0 0]

Rules:

- The first / every row must start with error bit location followed by rest of bit. i.e. leading coefficeint of a the polynomial must be 1
- Tail bits of a polynomial can be any 0/1 in a block size( we get in the array). Bitreversal is done for 5,6 to 6,5
- Once a error bit is processed in a block , we don't need to processs the bit again. Block window should slide further in search of next index / error bit to make a polynomial of fixed size
- Minimum polynomial size i.e. block of 5 is reasonable .
- polynomial size should not change during the execution.

Thank you!

Jogger
on 19 Nov 2020

Hi Adam,

Can you please help me wtih below issue ?

https://www.mathworks.com/matlabcentral/answers/653278-detect-overflow-for-full-range-and-resolution

Thank you!

### Accepted Answer

Image Analyst
on 26 Oct 2020

Try this:

fprintf('Beginning to run %s.m ...\n', mfilename);

y = [

0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0]

yMax = movmax(y, 5)

props = regionprops(yMax > 0, 'PixelIdxList') % Requires the Image Processing Toolbox.

for k = 1 : length(props)

fprintf('\nFor block #%d, indexes = ', k);

indexes{k} = props(k).PixelIdxList;

fprintf('%d ', indexes{k});

end

fprintf('\nDone running %s.m ...\n', mfilename);

You'll see:

For block #1, indexes = 5 6 7 8 9

For block #2, indexes = 39 40 41 42 43

For block #3, indexes = 73 74 75 76 77

##### 11 Comments

Jogger
on 26 Oct 2020

==================================================================

Your code will NOT work in case first elemet is set to 1. The block size will be reduced to 3 instead of 5 and this does not fit anymore to a predefined block size ( as you took 5 in movmax fcn)

For block #1, indexes = 1 2 3 ==> Bug "doesn't fit in a block"

For block #2, indexes = 5 6 7 8 9

For block #3, indexes = 39 40 41 42 43

For block #4, indexes = 73 74 75 76 77

Done running .m ...

Probably You have to change properties of movmax fcn

==================================================================

Looks good! Since I don't have a image processing toolbox to work on. Could you please help in imroving the below code?

siz_y = size(y,2);

[Val,idx] = find(y>0);

blockBits = zeros(1,5,size(idx,2));

blockindcs = zeros(1,5,size(idx,2));

for i = 1:size(idx,2)

a = idx(i);

if a>1 && a< siz_y

blockBits(:,:,i) = y(a-2:1:a+2);

blockindcs(:,:,i) = a-2:1:a+2;

elseif a==1

blockBits(:,:,i) = y(a:1:a+4);

blockindcs(:,:,i) = (a:1:a+4);

elseif a== siz_y

blockBits(:,:,i) = y(a-4:1:a);

blockindcs(:,:,i) = (a-4:1:a);

end

end

Image Analyst
on 26 Oct 2020

Are you sure? It's got to be the most common toolbox out there. I know it is here in Answers. Type ver on the command line to check.

If not, use find() to get the indexes of the 1's, and then use findgroups() to identify the separate blocks of them.

Jogger
on 27 Oct 2020

Thanks- can you please correct the error as I shared below

The code will NOT work in case first elemet is set to 1.

The block size will be reduced to 3 instead of 5 and this does not fit anymore to a predefined block size ( as you took 5 in movmax fcn)

For block #1, indexes = 1 2 3 ==> Bug "doesn't fit in a block"

For block #2, indexes = 5 6 7 8 9

For block #3, indexes = 39 40 41 42 43

For block #4, indexes = 73 74 75 76 77

Image Analyst
on 27 Oct 2020

So did you end up using my code? Or did you change it to use findgroups()? If so, attach that code.

If you're able to use the Image Processing Toolbox, you can use bwareaopen() to get rid of regions less than 5 in length:

fprintf('Beginning to run %s.m ...\n', mfilename);

y = [

0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0]

yMax = movmax(y, 5) > 0; % A logical vector.

yMax = bwareaopen(yMax, 5); % Keep runs of 5 or longer ONLY.

props = regionprops(yMax, 'PixelIdxList') % Requires the Image Processing Toolbox.

for k = 1 : length(props)

fprintf('\nFor block #%d, indexes = ', k);

blockIndexes{k} = props(k).PixelIdxList;

fprintf('%d ', blockIndexes{k});

end

fprintf('\nDone running %s.m ...\n', mfilename);

You'll see

For block #1, indexes = 5 6 7 8 9

For block #2, indexes = 39 40 41 42 43

For block #3, indexes = 73 74 75 76 77

Jogger
on 27 Oct 2020

Looks pretty good, But still improvement is required. Following Issues are observed & listed below

For block #1, indexes = 5 6 7 8 9

For block #2, indexes = 39 40 41 42 43

For block #3, indexes = 73 74 75 76 77

Issue -1:

Starting index is expected to be error bit i.e.I am expecting like below

For block #1, indexes = 7 8 9 6 5

For block #2, indexes = 41 42 43 40 39

For block #3, indexes = 75 76 77 74 73

Issue -2:

There is also a case where we have higher than block size is achieved. This mean higher polynomial order. This will NOT fit into pre-allocated buffer

[For block #1, indexes = 1 2 3 4 5 6 7 8 9 ]

Issue -3:

In case , if I modify y = errors positions(set to 1), I don't get the required output, For example, You can give a try by setting 1 and 101 locations ,

For block #1, indexes = 5 6 7 8 9

For block #2, indexes = 39 40 41 42 43

For block #3, indexes = 73 74 75 76 77

Done running .m ...

>> find(y>0)

ans =

1 7 41 75 101

Also please keep "bwareaopen" function c code translation, coder support is needed for c/c++ code generation, otherwise it is pretty difficult to implement on a 32 bit processor.

Thank you!

Image Analyst
on 27 Oct 2020

Jogger
on 28 Oct 2020

- What is the case where you had indexes 1-9?

In case - data altered for testing & verification

y = [

0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 1]

props =

3×1 struct array with fields:

PixelIdxList

For block #1, indexes = 1 2 3 4 5 6 7 8 9

- What do you expect to happen if you have 1's that are closer than 5 elements?

It's OK and they may be , after all 1 are the error bits. The expectation is , we should have constant block size and we don't need to process the already processed error bit in a block . Block must start with a error bit ( leading coefficient of a the polynomial must be 1). And block size should not change. In case block does

not accomadete all error bit, then process the error bit in next block . We should not repeat the already processed error bit.

- Is the solution to just add 2 to all the indexes?

No. If I understood your question correctly , you say adding/pad 2 additional bits. then my answer is you can do but finally we are not altering the output

- Area you saying that bwareaopen() is a function that is explicitly not included in the MATLAB Coder Toolbox?

No. I am saying bwareaopen(), I have to write the c code that might be difficult for me if i don't understand the details of bwareaopen()

Image Analyst
on 29 Oct 2020

You said "Also please keep "bwareaopen" function c code translation, coder support is needed for c/c++ code generation, otherwise it is pretty difficult to implement on a 32 bit processor." so I was assuming that you needed the whole program to be converted to C code with the Coder Toolbox because you were going to embed this algorithm in a custom chip on some device. If you don't need Coder support and are not going to generate C code, then I don't know why you said that. Please elaboarate. Also, I don't know that Coder can generate code for 32 bit processors. I know MATLAB stopped supporting 32 bit processors with version 2016b.

If you want

For block #1, indexes = 7 8 9 6 5

For block #2, indexes = 41 42 43 40 39

For block #3, indexes = 75 76 77 74 73

then you can just tack on the first two indexes to the end, like this:

fprintf('Beginning to run %s.m ...\n', mfilename);

y = [

0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0, ...

0 0 0 0 0 0 0 0 0]

windowWidth = 5;

halfWindowWidth = floor(windowWidth/2);

yMax = movmax(y, windowWidth) > 0; % A logical vector.

yMax = bwareaopen(yMax, windowWidth); % Keep runs of 5 or longer ONLY.

props = regionprops(yMax, 'PixelIdxList') % Requires the Image Processing Toolbox.

for k = 1 : length(props)

fprintf('\nFor block #%d, indexes = ', k);

theseIndexes = props(k).PixelIdxList';

blockIndexes{k} = [theseIndexes(end-halfWindowWidth : end), fliplr(theseIndexes(1:halfWindowWidth))];

fprintf('%d ', blockIndexes{k});

end

fprintf('\nDone running %s.m ...\n', mfilename);

It prints out:

For block #1, indexes = 7 8 9 6 5

For block #2, indexes = 41 42 43 40 39

For block #3, indexes = 75 76 77 74 73

Jogger
on 8 Nov 2020

### More Answers (0)

### See Also

### Community Treasure Hunt

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

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.