0

I need to calculate the following in matlab.

EDIT EDIT: I alway have a 16 x 3 matrix. 16 rows and 3 columns. The 3 columns represent R,G,B and the 16 rows represent points. From 1-16. An example matrix looks like this:

1 1 1
-1 0 0
0 0 1
1 0 0
-1 0 0
1 0 -1
1 1 1
1 1 1
0 0 0
-1 0 1
1 0 0
0 0 1
1 0 1
0 0 0
0 0 0
1 0 1

Now I need to know are there 11 coherently rows which have min. 1 value ~= 0 in each column? In the above example the first 8 rows and the last row have in each column min 1 value and are coherently. So this 9 rows are the max coherently rows without a complete zero row between.

Sry that my first post wasn't correct.

I've do that with a really poor for-solution. Is there a faster way (vectorized) to do that?

for i=1:16
   for j=0:16
      if i+j > 16
         value = (i+j)-16;
      else
         value = i+j;
      end
      if table(value,1) ~= 0 || table(value,2) ~= 0 || table(value,3) ~= 0
         equal = equal + 1;
         if equal >= 11
            copy(y,x) = 1;
            equal = 0;
            break;
         end
         else
            equal = 0;
         end
      end
   end
end

And the 16 points are circular. This min the first point and the last point connect.

Thanks for help and sry for the confusing.

AngelsEnd
  • 43
  • 5
  • your edit just confused the question. write a sample matrix, show your solution etc... – bla Feb 06 '15 at 08:47
  • Why not use a complete minimal sample data. You have used `1 1 1 1 0 1 1 0 0 0 -1 0 0 0 0 ` which is just a row vector and is enough to confuse others. Use a better sample data and post your loop solution! Thanks for helping us help you. – Divakar Feb 06 '15 at 09:15
  • yes you're right. Sorry for this. I EDIT my post again and hope my question is a bit more clear – AngelsEnd Feb 06 '15 at 11:37

2 Answers2

1

This counts the number of coherent rows with at least one none-zero entry without circularity:

B = ~(A==0);
idx = find(sum(B,2) == 0);
result = max([idx;size(A,1)+1] - [0;idx]) - 1;

Now you can check whether result is bigger than 11.

Another way would be:

B = ~(A==0);
C = bwconncomp(sum(B,2)>0);
num = cellfun(@numel,C.PixelIdxList);
result = max(num);

EDIT 2: To account for circularity, i.e. rows at the beginning and the end should be counted as coherent, you could do

B = ~(A==0);
idx = find(sum(B,2) == 0);
result = max([idx;size(A,1)+idx;size(A,1)+1] - [0;idx;size(A,1)+idx]) - 1;

EDIT: I edited the result-line in the first solution according to Knedlsepp's comments.

jolo
  • 423
  • 3
  • 10
0

This is a somewhat clunky solution, but it should give a solution at least if the matrix isn't too big. If you call your matrix m try the following line of code:

log2(max([cumprod(2*logical(m),2),ones(size(m,1),1)],[],2))

I hope this helps!

EDIT:

Now that it is clear what is ment by the question, here's an answer that should work:

find(~[m(:,1)|m(:,2)|m(:,3);0],1)-1 >= 11
Jens Boldsen
  • 1,255
  • 13
  • 21
  • I think this fails on vectors like `[0 1 1 0 1]` but you're at the right direction.... – bla Feb 06 '15 at 08:18
  • yes. Thanks @ Jens but fails on vectors which not beginn with 1 – AngelsEnd Feb 06 '15 at 08:24
  • I've edited my answer so it works in the case where the first entry is zero too. You should notice however that my solution is not always faster than a simple `for` loop using something like `find([m(i,:),0]==0,1)-1`. If there are many rows my solution is best, if there are many columns the `for` solution is better. – Jens Boldsen Feb 06 '15 at 08:32
  • Sry for that mistake but I edit my main-post because my question wasn't correct. – AngelsEnd Feb 06 '15 at 08:45