using find() in matlab - matlab

Say I have a matrix A of dimension Nx3 where N is the number of rows. A stores coordinates x,y,z. Now say I already have a set of known coordinates B = [x' y' z'] which I wanna look up in A. I wanna find out the number of which row index in A stores (x',y',z'). How can I do this? I am guessing I will have to use find()

you can use find, for example
find(A(:,1)==B(1) & A(:,2)==B(2) & A(:,3)==B(3))
will yield the index of the row\rows that match.
Try to get use to reading the documentation of Matlab, it is all there...
by the way, an alternative is to use ismember:
[~,id]=ismember(B,A,'rows')
the variable id will yield the index of the rows where B matched A.

Related

Build a matrix starting from instances of structure fields in MATLAB

I'm really sorry to bother so I hope it is not a silly or repetitive question.
I have been scraping a website, saving the results as a collection in MongoDB, exporting it as a JSON file and importing it in MATLAB.
At the end of the story I obtained a struct object organised
like this one in the picture.
What I'm interested in are the two last cell arrays (which can be easily converted to string arrays with string()). The first cell array is a collection of keys (think unique products) and the second cell array is a collection of values (think prices), like a dictionary. Each field is an instance of possible values for a set of this keys (think daily prices). My goal is to build a matrix made like this:
KEYS VALUES_OF_FIELD_1 VALUES_OF_FIELD2 ... VALUES_OF_FIELDn
A x x x
B x z NaN
C z x y
D NaN y x
E y x z
The main problem is that, as shown in the image and as I tried to explain in the example matrix, I don't always have a value for all the keys in every field (as you can see sometimes they are 321, other times 319 or 320 or 317) and so the key is missing from the first array. In that case I should fill the missing value with a NaN. The keys can be ordered alphabetically and are all unique.
What would you think would be the best and most scalable way to approach this problem in MATLAB?
Thank you very much for your time, I hope I explained myself clearly.
EDIT:
Both arrays are made of strings in my case, so types are not a problem (I've modified the example). The main problem is that, since the keys vary in each field, firstly I have to find all the (unique) keys in the structure, to build the rows, and then for each column (field) I have to fill the values putting NaN where the key is missing.
One thing to remember you can't simply use both strings and number in one matrix. So, if you combine them together they can be either all strings or all numbers. I think all strings will work for you.
Before make a matrix make sure that all the cells have same element.
new_matrix = horzcat(keys,values1,...valuesn);
This will provide a matrix for each row (according to your image). Now you can use a for loop to get matrices for all the rows.
For now, I've solved it by considering the longest array of keys in the structure as the complete set of keys, let's call it keys_set.
Then I've created for each field in the structure a Map object in this way:
for i=1:length(structure)
structure(i).myMap = containers.Map(structure(i).key_field, structure(i).value_field);
end
Then I've built my matrix (M) by checking every map against the keys_set array:
for i=1:length(keys_set)
for j=1:length(structure)
if isKey(structure(j).myMap,char(keys_set(i)))
M(i,j) = string(structure(j).myMap(char(keys_set(i))));
else
M(i,j) = string('MISSING');
end
end
end
This works, but it would be ideal to also be able to check that keys_set is really complete.
EDIT: I've solved my problem by using this function and building the correct set of all the possible keys:
%% Finding the maximum number of keys in all the fields
maxnk = length(structure(1).key_field);
for i=2:length(structure)
if length(structure(i).key_field) > maxnk
maxnk = length(structure(i).key_field);
end
end
%% Initialiting the matrix containing all the possibile set of keys
keys_set=string(zeros(maxnk,length(structure)));
%% Filling the matrix by putting "0" if the dimension is smaller
for i=1:length(structure)
d = length(string(structure(i).key_field));
if d == maxnk
keys_set(:,i) = string(structure(i).key_field);
else
clear tmp
tmp = [string(structure(i).key_field); string(zeros(maxnk-d,1))];
keys_set(:,i) = tmp;
end
end
%% Merging without duplication and removing the "0" element
keys_set = union_several(keys_set);
keys_set = keys_set(keys_set ~= string(0));

How to retrieve specific rows that the coordinates x,y have been saved in another matrix?

I have a data matrix Data(8765x138) that first and second columns are x and y coordinates. I have sampled some specific points in another array, Points(2000x2), first and second columns in A refers to x and y, respectively. I want to extract some specific rows in Matlab that match with matrix A (both x,y). The output should be (2000x138). I tried the following code but the result is not correct.
newData = Data(ismember(Data(:,1),Points(:,1))& ismember(Data(:,2),Points(:,2)),:);
what should I do to select the rows from Data that its first and second columns match to my Points matrix. Someone please help, I feel like I've tried everything!
You can use ismember with argument rows
newData = Data(ismember(Data(:,1:2),Points(:,1:2),'rows'),:);
But when you are sampling it is better to save index of sampled data and use them to extract coordinates.
It's a badly worded question, so hard to know for sure, but the solution might be to use ismember() to find matching rows, e.g.:
DataXY = Data(:,[1,2]);
tf = ismember(DataXY, Points, 'rows');
newData = Data(tf,:);

find in multidimensional array - MATLAB

I have a 3 by 3 by 2 by 3 array X containing 1s or 0s. Picture this as a row of three 3 by 3 matrices along a row and another such 'layer' behind them (from the '2').
I want to find the positions in X of the 0s in the first layer and second layer separately. I'm not really sure how to do this with find, but heuristically something like:
A = find(X == 0 & 3rd index of X is 1)
B = find(X == 0 & 3rd index of X is 2)
EDIT
I just realised my attempt to simplify my actual question made it misleading. The array X actually has -1's, 1's and -2's and I want to find the -2's. They're not meant to be logical operators. Also I would prefer any operation proposed to be as fast as possible as this will be part of a recursive backtracking algorithm.
solution using logical indexing
I recommend to use logical indexing instead of find.
This gives you all indices where X is 1
value_you_want=-2
C=X==value_you_want;
Now you want only parts of these indices in A and B, first initialize A and B with false of the same size as C:
A=false(size(C));
B=A;
And finally copy the slice you want to each of these matrices:
A(:,:,1,:)=C(:,:,1,:);
B(:,:,2,:)=C(:,:,2,:);
If you really want your numeric indices, use find(A) and find(B)
Alternative solution using linear indices and find
%get all indices
C=find(X==value_you_want)
%convert linear indices to subscript indices, only use third dimension
[~,~,S,~]=ind2sub(size(X),find(X==0));
%Use S to split C
A=C(S==1);
B=C(S==2);
Generally use find(condition) to return linear indices in the array satisfying condition.
A = find(A(:,:,1,:)<1)
B = find(A(:,:,2,:)<1)

Assigning the different row to another matrix after comparing two matrices

i have two matrices
r=10,000x2
q=10,000x2
i have to find out those rows of q which are one value or both values(as it is a two column matrix) different then r and allocate them in another matrix, right now i am trying this.i cannot use isequal because i want to know those rows
which are not equal this code gives me the individual elements not the complete rows different
can anyone help please
if r(:,:)~=q(:,:)
IN= find(registeredPts(:,:)~=q(:,:))
end
You can probably do this using ismember. Is this what you want? Here you get the values from q in rows that are different from r.
q=[1,2;3,4;5,6]
r=[1,2;3,5;5,6]
x = q(sum(ismember(q,r),2) < 2,:)
x =
3 4
What this do:
ismember creates an array with 1's in the positions where q == r, and 0 in the remaining positions. sum(.., 2) takes the column sum of each of these rows. If the sum is less than 2, that row is included in the new array.
Update
If the values might differ some due to floating point arithmetic, check out ismemberf from the file exchange. I haven't tested it myself, but it looks good.

Finding coordinates of maximum values of a matrix

I'm trying to find a way to find the sets of coordinates of the maximum value/s in a matrix of size [8,8], where the values in the matrix vary from 0 to 6 (generated through the rest of the script/function).
i.e. a matrix of zeros(8,8) where the value 1 is in [3,3], [3,5] and [5,3].
and I want to get returned something along the lines of ([3,3],[3,5],[5,3])
I have tried using things such as ind2sub, etc but with no luck (I keep getting things returned like [I,J] = [ [0,0,3,0,5,0,0,0] , [1,1,1,1,1,1,1,1] ])
Any ideas?
If more clarification is needed, just point out where you need it and I'd be glad to do so.
The problem you've been having with max so far is because it operates on one dimension. If you call it on a matrix, using its default parameters, it will return a single maximum element (and indices) for each column of the matrix. In your case, you want all maximums, and the global maximum at that.
Try this:
[I,J] = find(M == max(M(:)))
First, max(M(:)) finds the maximum element, then we construct a logical matrix M == max(M(:)) showing which elements are the maximum. Finally, you can use find to get the co-ordinates of those (if necessary).