From: Marit on
I have a matrix of 1's and 0's, and I want to find sequences of 1's and find the element in the middel of the subsequence, and then define a new matrix (same size as my original matrix) with just a 1 at this middle position. If the number of 1's in a sequence is even the 1 is put in the position of the right-most element of the two elements in the middle.

For example if I have the matrix [0 0 1 1 1 0 0 0
0 1 1 1 1 0 0 0
1 0 0 0 1 1 1 0]

I want to get the new matrix [0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
1 0 0 0 0 1 0 0]

Anyone who knows how to do?
From: dpb on
Marit wrote:
> I have a matrix of 1's and 0's, and I want to find sequences of 1's and
> find the element in the middel of the subsequence, and then define a new
> matrix (same size as my original matrix) with just a 1 at this middle
> position. If the number of 1's in a sequence is even the 1 is put in the
> position of the right-most element of the two elements in the middle.
> For example if I have the matrix [0 0 1 1 1 0 0 0
> 0 1 1 1 1 0 0 0
> 1 0 0 0 1 1 1 0]
>
> I want to get the new matrix [0 0 0 1 0 0 0 0
> 0 0 0 1 0 0 0 0
> 1 0 0 0 0 1 0 0]
>
> Anyone who knows how to do?

I usually start on such beasties w/ diff() to locate the runs -- the the
transitions are marked by +/-1; the runs by 0's. Then one can work thru
the difference vector and construct the desired result.

find(), of course, will return all the 1's and can be used similarly.

In this case I've not thought thru enough to have a real preference.

--
From: Jan Simon on
Dear Marit!

> For example if I have the matrix [0 0 1 1 1 0 0 0
> 0 1 1 1 1 0 0 0
> 1 0 0 0 1 1 1 0]
>
> I want to get the new matrix [0 0 0 1 0 0 0 0
> 0 0 0 1 0 0 0 0
> 1 0 0 0 0 1 0 0]

If your array is small (< 1e6 elements), you can solve this iteratively:
Use FINDSTR to find all [0, 1, 1] seqences in a row and replace them by [0, 0, 1]. Then the same for [1, 1, 0] -> [1, 0, 0]. Proceed until the result did not change anymore.
Loop over all rows.
Ready.


This is obviously not efficient. But if you have to do this just a few times, finding a smart solution will take more time than you can save with an efficient processing! --- Except that Bruno find the smart solution for you.

Kind regards, Jan
From: Bruno Luong on
You could use an utility call SplitVec in FEX

http://www.mathworks.com/matlabcentral/fileexchange/24255

A = [0 0 1 1 1 0 0 0;
0 1 1 1 1 0 0 0;
1 0 0 0 1 1 1 0];

% Engine
mfun = @(x) accumarray([1 ceil((length(x)+1)/2)], x(1), size(x));
for r=1:size(A,1)
c = SplitVec(A(r,:), [], mfun); % FEX
A(r,:) = cat(2,c{:});
end

% Check
A

A =

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

% Bruno
From: Bruno Luong on
A slightly more compact code:

% Engine
mfun = @(x) accumarray([1 ceil((length(x)+1)/2)], x(1), size(x));
sfun = @(r) cell2mat(SplitVec(r, [], mfun));
for r=1:size(A,1)
A(r,:) = sfun(A(r,:));
end

% Bruno
 | 
Pages: 1
Prev: custom fit
Next: video compression matlab code