Suggest an Alternate for Nonzero (nnz) built-in function

6 views (last 30 days)
Hi,
So I have a binary matrix of size 2000 by 256.
I start with a standard all-zero matrix of size some 'X' by 256 as my column size is static. I keep filling binary data row by row in a sequential manner. So to see how much I have filled up, I use this line of code
nnz(any(MyBinaryMatrix(1 : end, :), 2);
So that all zero rows are not considered and only filled up rows are.
Now my Matrix has changed to some 'X' by 32. My columns became smaller, but same steps as above. Sometimes when I add my new binary data row, rarely some of them can potentially be a zero row (part of process), and hence now if I use 'nnz', I get discrepancies.
This zero row can randomly be anywhere in between more than atleast once. I still need to see how many rows filled up. I use it as a control variable for while loop.
How can I see how many rows I filled up without nnz? Any help is appreciated.
  1 Comment
dpb
dpb on 17 Nov 2022
This is very confusing about what you're trying to describe what it is you're really trying to do...for starters
nnz(any(MyBinaryMatrix(1 : end, :), 2);
Invalid expression. When calling a function or indexing a variable, use parentheses. Otherwise, check for mismatched delimiters.
is a syntax error w/ mismatched parentheses. So, guessing that you had a typo and intended
nnz(any(MyBinaryMatrix(1 : end, :), 2));
instead, then that's much more succinctly written as just
N=nnz(any(MyBinaryMatrix,2));
and will count the number of rows in the array that have at least one nonzero element in them...it says nothing about which rows may be the ones that are the "empty" ones versus "non-empty" ones; that's what the result of the any operation return vector will give you.
If you assign new data that can be at any row in the array and that new data can be a row of all zero, then, indeed, you can certainly change the number of "filled" rows to increase the "empty" rows; that will, in fact, be just what happened.
If you don't want that to happen, then you must keep track of which specific rows have been written and not mess with them any further or do the assignment sequentially and not allow the row address to backtrack over previoulsy-written rows...which would then necessitate not leaving that row until it is no longer "empty", or the final result can accept there being some empty rows when done.
We have no klew just what the process is or the end result, but the problem here isn't nnz, it's the logic of the application of the function -- it apparently isn't the actual answer you're needing here. It may be part of the solution, but clearly isn't all.
As a side point, the same issue is going to be extant regardless of the size of the arrays -- it may just be hidden with the larger array because the likelihood of generating a 256-vector of all zero is vanishingly small so you just didn't see it.

Sign in to comment.

Accepted Answer

Voss
Voss on 17 Nov 2022
"I keep filling binary data row by row in a sequential manner."
If you are going row-by-row, one row at a time, keep track of which row you're on:
current_row = 1;
while true
% ...
% do some process
% ...
% ...
% fill in current_row row
% ...
current_row = current_row + 1; % increment current_row
end
"How can I see how many rows I filled up without nnz?"
At any given point, you'll know how many rows have been filled - regardless of whether they were all zeros or not - based on the value of current_row.

More Answers (2)

Steven Lord
Steven Lord on 17 Nov 2022
You can keep track of the next row to be filled. When you add data to a row, increment that tracking variable.
x = zeros(6, 3);
nextRow = 1;
while nextRow <= size(x, 1)
y = randi(10, 1, 3);
if rand > 0.5
fprintf("Adding row %s as row %d of x.\n", mat2str(y), nextRow)
x(nextRow, :) = y;
nextRow = nextRow + 1;
else
fprintf("NOT adding row %s as row %d of x.\n", mat2str(y), nextRow)
end
end
NOT adding row [1 7 9] as row 1 of x.
Adding row [1 4 7] as row 1 of x.
NOT adding row [4 6 3] as row 2 of x.
Adding row [2 3 6] as row 2 of x. Adding row [4 7 2] as row 3 of x. Adding row [10 2 5] as row 4 of x.
NOT adding row [5 6 8] as row 5 of x. NOT adding row [4 3 6] as row 5 of x. NOT adding row [2 5 1] as row 5 of x.
Adding row [8 8 1] as row 5 of x. Adding row [3 8 9] as row 6 of x.
disp(x)
1 4 7 2 3 6 4 7 2 10 2 5 8 8 1 3 8 9

Walter Roberson
Walter Roberson on 17 Nov 2022
Keep an extra row_has_been_filled variable that is initialized to false(X, 1) . Set row_has_been_filled(ROWNUMBER) = true when it is written into. nnz(~row_has_been_filled) would be the number of available rows.

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!