Find first occurrence of any number of a vector - matlab

I want to find the first occurrence of either 2,3 or 5 in x. The output should be 7 as 3 appears first at index 7. How do I do that?
x = [0 0 0 0 1 1 3 5 2 0 0];
y = [2 3 5];
output = 7
I can use find(x == 3, 1) to find just one number but how do I do that for multiple numbers?
Thanks

MATLABs find is already the right choice in combination with ismember
In this case
>> find(ismember(x,y),1)
will do what you want. It returns the index of the first occurence of array y in array x. This will work for any lengths y might have.

Find() accepts a logical term as an argument, so you can use your call but instead of checking only for 3, use something like:
(x==2 || x==3 || x==5)
I'm general, you might want to use the intersect() function.

Related

Comparing Vectors of Different Length

I am trying to compare two vectors of different size. For instance when I run the code below:
A = [1 4 3 7 9];
B = [1 2 3 4 5 6 7 8 9];
myPadded = [A zeros(1,4)];
C = ismember(myPadded,B)
I get the following output:
C = 1 1 1 1 1 0 0 0 0
However, I want an output that will reflect the positions of the compared values, hence, I would like an output that is displayed as follows:
C = 1 0 1 1 0 0 1 0 1
Please, I need some help :)
There are 2 points. First, you are writing the inputs of ismember in the wrong order. Additionally, you do not need to grow your matrix. Simply try ismember(B, A) and you will get what you expect.
The function ismember(myPadded, B) returns a vector the same size of myPadded, indicating if the i-th element of myPadded is present in B.
To get what you want, just invert parameter order: ismember(B, myPadded).
A quick way of doing this is to use logical indexing. This will only work if the last digit of B is included in A.
A = [1 4 3 7 9];
c(A) = 1; % or true.
An assumption here is that you want to subindex a vector 1:N, so that B always is B = 1:N. In case the last digit is not one this is easy to fix. Just remember to return all to its previous state after you are done. It will be 2 rows extra though.
This solution is meant as a special case working on a very common problem.

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

MATLAB syntax length

I'm reading some MATLAB trying to pick it up. The line below is probably rather simple but I do not understand it.
I understand length will give me the length of a vector, in this case a vector which is part of a struct, index_struct.data_incl.
The actual value of index_stuct.data_incl at run time is simply 1. What is confusing me is what is inside the brackets i.e. (index_struct.data_incl == 1)? I can't work out what this line is trying to do as simple as it may be!
int_var = length(index_struct.data_incl(index_struct.data_incl == 1));
try this (but think of x as your index_struct.data_incl:):
x = [1 4 5 13 1 1]
length(x(x==1))
ans =
3
It's just counting the number of elements of your x vector that are equal to 1
because x==1 evaluates to [1 0 0 0 1 1] and then using logical indexing x(x==1) evaluates to [1 1 1] whose length is 3;
It could have been written more simply as sum(index_struct.data_incl == 1)
If I dont see the code I can only guess..., but I guess that index_struc.data_incl should be a vector, with length n meaning that you have the option to read until n files, and all the values of the array should be 0 at the begining, and when you read a file you change the corresponding position in the vector index_struc.data_incl from 0 to 1. After some time you can see how many of these files you have read using
int_var = length(index_struct.data_incl(index_struct.data_incl == 1));
because it will give to you the number of 1 in the vector index_struct.data_incl.

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.

How do I get the indexes of specific elements based on value and then replace them in MATLAB?

From the exercises in a book I am using to learn MATLAB:
Given x = [3 15 9 12 -1 0 -12 9 6 1],
provide the command(s) that will
A) set the values of x that are
positive to zero
B) set values that are multiples of 3
to 3 (rem will help here)
C) multiply the values of x that are
even by 5
D) extract the values of x that are
greater than 10 into a vector called
y
E) set the values in x that are less
than the mean to zero
F) set the values in x that are above the mean to their difference from the mean
Question a) will teach you the following elements:
find a function that returns indexes given a condition, in your case x>0
use indexing in order to set selected values in x to 0
to be continued ...
x = [3 15 9 12 -1 0 -12 9 6 1]
vi = (x < 0) % statement that returns a boolean, gives a vector like
% [0 0 0 0 1 0 1 0 0 0]
x(vi) = -x(vi) % does the operation (negating in this case) on the relevant
% values of x (those with a 1 from above)
Without actually doing your homework, they all follow the above pattern.
I agree with the comments to your question, that is not necessarily the right way to go if you really want to learn something.
As to answer your question, MATLAB has a fantastic function browser I strongly suggest you take a look at it. With well chosen keywords you can go a long way. :)