Find Index of Zero or Almost Zero Rows - matlab

I have a NxM matrix with mixed rows
A = [[1.1 2.2 3.0]; [0.00000009 0 0]; [0 0 0]; [1 2 3]];
I want to find indices of all zero rows in A. From link I've tried
find(all(A==0,2))
and I am able to get the index of 3rd row i.e. [0 0 0] but not 2nd row which is also almost zero. How can i find all such rows which are either all zero or almost very near to zero.
I've used the following as work around but I don't think so its the correct way to solve this problem.
idx = unique([find(all(A<0.000001,2));find(all(A==0,2))]);
What is the correct way? Thanks for any help

First, define what you count as "almost very near to zero":
inc=1E-5;
Then, match the search to that criteria:
idx=find(all(abs(A)<inc,2))
The result is:
idx =
2
3

Related

How to get the logical matrix corresponding to "scatter" plot?

If I have a two column matrix A like below, I can plot the scatter plot using scatter/plot command. I would like to get the matrix corresponding to such outputs as in hist command. hist command gives the vector output too.
A=[7 1;3 2; 4 3]
For example out=scatter(A(:,1),A(:,2)) must give something like below:
[0 0 0;
0 0 0;
0 1 0;
0 0 1;
0 0 0;
0 0 0;
1 0 0]
Only the indices (7,1), (3,2) and (4,3) are only ones. Or Can someone give me a snippet code to realize this without using loops?
You can use a combination of sparse and full where you can specify the non-zero row and column locations, and the rest of the matrix would be zero:
A = [7 1; 3 2; 4 3];
B = full(sparse(A(:,1), A(:,2), 1, max(A(:,1)), max(A(:,2)))) == 1;
The sparse command takes in the row and column locations of what is non-zero for the first two inputs, the third input is what the non-zero location would be for each row and column location. We can specify a constant to mean that every non-zero location gets the same coefficient, which is 1. We can also specify the size of the matrix, where in this case the rows and columns of the output correspond to the largest number in the first and second columns respectively. Because this is a sparse matrix, you will want to convert this to a full matrix and because you want it to be logical, you will want to compare all elements with the number 1.
We thus get for the output, which is B:
B =
7×3 logical array
0 0 0
0 0 0
0 1 0
0 0 1
0 0 0
0 0 0
1 0 0
Alternatively, we can use sub2ind to create linear indices to index into a pre-allocated matrix of logical false and set only those non-zero row locations to true:
A = [7 1; 3 2; 4 3];
B = false(max(A(:,1)), max(A(:,2)));
ind = sub2ind(size(B), A(:,1), A(:,2));
B(ind) = true;
We first allocate the matrix, then calculate the linear indices to index into the matrix, then finally set the right locations to true. The output here would be the same as the sparse approach.
Just to add: rayryeng's solution is fine if you really want your result to be logical in the sense that it is equal to one if there is anything at the coordinate and zero otherwise. Still, since you added a note on hist, I was wondering if you actually want to count the number of times a specific coordinate is hit. In this case, consider using
S = histcounts2(A(:,2),A(:,1));
if you have access to R2015b+. If not, there is a hist2 function on fileexchange you can use for the purpose.
Here is my solution. Matlab provides a command called accumarray.
S = logical(accumarray(A, 1) )
will give the result too.

What does it mean to use logical indexing/masking to extract data from a matrix? (MATLAB)

I am new to matlab and I was wondering what it meant to use logical indexing/masking to extract data from a matrix.
I am trying to write a function that accepts a matrix and a user-inputted value to compute and display the total number of values in column 2 of the matrix that match with the user input.
The function itself should have no return value and will be called on later in another loop.
But besides all that hubbub, someone suggested that I use logical indexing/masking in this situation but never told me exactly what it was or how I could use it in my particular situation.
EDIT: since you updated the question, I am updating this answer a little.
Logical indexing is explained really well in this and this. In general, I doubt, if I can do a better job, given available time. However, I would try to connect your problem and logical indexing.
Lets declare an array A which has 2 columns. First column is index (as 1,2,3,...) and second column is its corresponding value, a random number.
A(:,1)=1:10;
A(:,2)=randi(5,[10 1]); //declares a 10x1 array and puts it into second column of A
userInputtedValue=3; //self-explanatory
You want to check what values in second column of A are equal to 3. Imagine as if you are making a query and MATLAB is giving you binary response, YES (1) or NO (0).
q=A(:,2)==3 //the query, what values in second column of A equal 3?
Now, for the indices where answer is YES, you want to extract the numbers in the first column of A. Then do some processing.
values=A(q,2); //only those elements will be extracted: 1. which lie in the
//second column of A AND where q takes value 1.
Now, if you want to count total number of values, just do:
numValues=length(values);
I hope now logical indexing is clear to you. However, do read the Mathworks posts which I have mentioned earlier.
I over simplified the code, and wrote more code than required in order to explain things. It can be achieved in a single-liner:
sum(mat(:,2)==userInputtedValue)
I'll give you an example that may illustrate what logical indexing is about:
array = [1 2 3 0 4 2];
array > 2
ans: [0 0 1 0 1 0]
using logical indexing you could filter elements that fullfil a certain condition
array(array>2) will give: [3 4]
you could also perform alterations to only those elements:
array(array>2) = 100;
array(array<=2) = 0;
will result in "array" equal to
[0 0 100 0 100 0]
Logical indexing means to have a logical / Boolean matrix that is the same size as the matrix that you are considering. You would use this as input into the matrix you're considering, and any locations that are true would be part of the output. Any locations that are false are not part of the output. To perform logical indexing, you would need to use logical / Boolean operators or conditions to facilitate the selection of elements in your matrix.
Let's concentrate on vectors as it's the easiest to deal with. Let's say we had the following vector:
>> A = 1:9
A =
1 2 3 4 5 6 7 8 9
Let's say I wanted to retrieve all values that are 5 or more. The logical condition for this would be A >= 5. We want to retrieve all values in A that are greater than or equal to 5. Therefore, if we did A >= 5, we get a logical vector which tells us which values in A satisfy the above condition:
>> A >= 5
ans =
0 0 0 0 1 1 1 1 1
This certainly tells us where in A the condition is satisfied. The last step would be to use this as input into A:
>> B = A(A >= 5)
B =
5 6 7 8 9
Cool! As you can see, there isn't a need for a for loop to help us select out elements that satisfy a condition. Let's go a step further. What if I want to find all even values of A? This would mean that if we divide by 2, the remainder would be zero, or mod(A,2) == 0. Let's extract out those elements:
>> C = A(mod(A,2) == 0)
C =
2 4 6 8
Nice! So let's go back to your question. Given your matrix A, let's extract out column 2.
>> col = A(:,2)
Now, we want to check to see if any of column #2 is equal to a certain value. Well we can generate a logical indexing array for that. Let's try with the value of 3:
>> ind = col == 3;
Now you'll have a logical vector that tells you which locations are equal to 3. If you want to determine how many are equal to 3, you just have to sum up the values:
>> s = sum(ind);
That's it! s contains how many values were equal to 3. Now, if you wanted to write a function that only displayed how many values were equal to some user defined input and displayed this event, you can do something like this:
function checkVal(A, val)
disp(sum(A(:,2) == val));
end
Quite simply, we extract the second column of A and see how many values are equal to val. This produces a logical array, and we simply sum up how many 1s there are. This would give you the total number of elements that are equal to val.
Troy Haskin pointed you to a very nice link that talks about logical indexing in more detail: http://www.mathworks.com/help/matlab/math/matrix-indexing.html?refresh=true#bq7eg38. Read that for more details on how to master logical indexing.
Good luck!
%% M is your Matrix
M = randi(10,4)
%% Val is the value that you are seeking to find
Val = 6
%% Col is the value of the matrix column that you wish to find it in
Col = 2
%% r is a vector that has zeros in all positions except when the Matrix value equals the user input it equals 1
r = M(:,Col)==Val
%% We can now sum all the non-zero values in r to get the number of matches
n = sum(r)
M =
4 2 2 5
3 6 7 1
4 4 1 6
5 8 7 8
Val =
6
Col =
2
r =
0
1
0
0
n =
1

Replace zero values in vector

Ive got a vector like this
a=[0 5 3 0 1]
and a corresponding vector, containing the same amount of numbers as there are zeros in the first vector
b=[2 4]
what I want to get is
x=[2 5 3 4 1]
I tried fiddling around with, and somewhat got the feeling that the find / full methods might help me here, but didn't get it to work
c=(a==0)
>[1 0 0 1 0]
Thank you!
It is as easy as this:
x=a;
As x==0 gives the vector of all the locations an element = 0, ie [0 1 0 0 1], x(x==0) is indexing x to get the actual elements of x that are equal to 0, which you can then assign values as if it were any other vector/matrix (where the values we are not interested in do not exist, and are not indexed), using the following:
x(x==0)=b;

Deleting columns in array with zeros

I have an array that starts of with zeros and continues into other numbers
I would like to delete the columns in the array that start off with zero but keep the other numbers
example of an column array below:
x= [0 0 0 0 0 2 4 6 8 0 1 2];
Answer of column array would look like
x= 2 4 6 8 0 1 2
I'm using octave 3.4.2/matlab
Thanks
Here is the code:
x = x(find(x~=0, 1):end);
or
x(1:find(x~=0,1)-1) = [];
The find command should work for this.
Assuming your vector is x:
find(x ~= 0)
Will return all indices where x is non-zero. Just grab the first index and go from there to delete all values from 1 to index.
Logical indexing will work just fine in this case: i.e.,
y = x(:,x(1,:)~=0)
will do the job for you. The inner logical comparison, x(1,:)~=0 returns true for every column whose first element is not zero. The indexing operation, x(:,...) selects only those columns for which the logical comparison returned true.

Counting the number of elements in matlab

I am new to MATLAB. Suppose I have a vector like x = [1 1 1 1 1 1 0 0 1 0]. I want to calculate the total number of elements in the vector and the number of non zero elements in the vector. Then come up with a ratio of both the numbers. I am searching in MATLAB help. how to do count of elements, but till now I didn't get any luck. If anyone provide me with help, it would be of great help. Thanks in advance.
You can get the number of elements with numel(x).
You can get the number of non-zeros with sum(x ~= 0).
So the ratio is one divided by the other.
The right way to find the number of nonzero elements (in general) is to use the nnz() function; using sum() also works in this particular case but will fail if there are numbers other than zero and one in the matrix used. Therefore to calculate the total element count, nonzero element count, and ratio, use code like this:
x = [1 1 1 1 1 1 0 0 1 0];
nonzeroes = nnz(x);
total = numel(x);
ratio = nonzeroes / total;
The ratio of non-zero elements to all elements in a vector is:
r = length(find(x)) / length(x)
What length does is kind of obvious. find gives you the index of all non-zero elements.
Edit: Fixed mistake of using size instead of length.
a= numel(find(x))/numel(x) is another way to do it.