Find specific union of two arrays with different length in MATLAB - arrays

I have a coding problem in Matlab, where I try to find a solution without too many for-loops slowing down the process.
I have an array that looks like:
A = [1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,5]
Another that looks like:
B = [0,1,0,1,1]
In B there's always as many elements as their are unique elements in A and the value corresponds to the unique element in A, in other words:
length(unique(A)) = length(B)
I want to compute a result that tells me the index where B == 0 (C) and B == 1 (D) in A.
C = [1,2,3,9,10,11,12]
D = [4,5,6,7,8,13,14,15,16,17,18]

Here is my approach: first "calculate" Au as unique vector of A. In the next step use B for logical indexing of Au: Au( logical(B) ) - this gets the values to be found in A. Then check which values are member of this group and then get their indices. There may be a simpler approach though.
A = [1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,5]
Au = unique( A );
B = [0,1,0,1,1];
C = find( ismember( A, Au( logical(B) ) ) )
D = find( ismember( A, Au( ~logical(B) ) ) )

Related

How to insert NaN in an array if it is missing values that are present in another array?

Assume I have two arrays:
A = [850;950;1000;1050;1100];
B = [850;950;1000;1100];
Here B is missing the value 1050 that is present in array A. As I later would like to compare A and B logically I would like to fill this missing place with a NaN thus giving me
B = [850;950;1000;NaN;1100];
What is the fastest way to do this in Matlab?
I would create a copy of A, and NaN out any values which aren't a member of B. This is easier than inserting NaNs in the correct places of B...
C = A;
C( ~ismember( A, B ) ) = NaN;
Optionally, you can assign B = C at the end.
Alternatively you can avoid copying all of A, and just assign the index to a variable, this is purely a preference thing...
idx = ~ismember( A, B );
B = A;
B( idx ) = NaN;

How to extract different values/elements of matrix or array without repeating?

I have a vector/ or it could be array :
A = [1,2,3,4,5,1,2,3,4,5,1,2,3]
I want to extract existing different values/elements from this vector without repeating:
1,2,3,4,5
B= [1,2,3,4,5]
How can I extract it ?
I would appreciate for any help please
Try this,
A = [1,2,3,4,5,1,2,3,4,5,1,2,3]
y = unique(A)
B = unique(A) returns the same values as in a but with no repetitions. The resulting vector is sorted in ascending order. A can be a cell array of strings.
B = unique(A,'stable') does the same as above, but without sorting.
B = unique(A,'rows') returns the unique rows ofA`.
[B,i,j] = unique(...) also returns index vectors i and j such that B = A(i) and A = B(j) (or B = A(i,:) and A = B(j,:)).
Reference: http://cens.ioc.ee/local/man/matlab/techdoc/ref/unique.html
Documentation: https://uk.mathworks.com/help/matlab/ref/unique.html
The answers below are correct but if the user does not want to sort the data, you can use unique with the parameter stable
A = [1,2,3,4,5,1,2,3,4,5,1,2,3]
B = unique(A,'stable')

Count items in one cell array in another cell array matlab

I have 2 cell arrays which are "celldata" and "data" . Both of them store strings inside. Now I would like to check each element in "celldata" whether in "data" or not? For example, celldata = {'AB'; 'BE'; 'BC'} and data={'ABCD' 'BCDE' 'ACBE' 'ADEBC '}. I would like the expected output will be s=3 and v= 1 for AB, s=2 and v=2 for BE, s=2 and v=2 for BC, because I just need to count the sequence of the string in 'celldata'
The code I wrote is shown below. Any help would be certainly appreciated.
My code:
s=0; support counter
v=0; violate counter
SV=[]; % array to store the support
VV=[]; % array to store the violate
pairs = ['AB'; 'BE'; 'BC']
%celldata = cellstr(pairs)
celldata = {'AB'; 'BE'; 'BC'}
data={'ABCD' 'BCDE' 'ACBE' 'ADEBC '} % 3 AB, 2 BE, 2 BC
for jj=1:length(data)
for kk=1:length(celldata)
res = regexp( data(jj),celldata(kk) )
m = cell2mat(res);
e=isempty(m) % check res array is empty or not
if e == 0
s = s + 1;
SV(jj)=s;
v=v;
else
s=s;
v= v+1;
VV(jj)=v;
end
end
end
If I am understanding your variables correctly, s is the number of cells which the substring AB, AE and, BC does not appear and v is the number of times it does. If this is accurate then
v = cellfun(#(x) length(cell2mat(strfind(data, x))), celldata);
s = numel(data) - v;
gives
v = [1;1;3];
s = [3;3;1];

How do I assign index entries found using matlab ismember to another array?

I have two vectors P and D. I have written the following code which looks at each element of D and then finds the same element in P (both have same elements just in different order) and returns the index of that element in P. The following code is able to do that.
for i=1:17
ind = find(ismember(P,D(i)));
ind
msgbox(sprintf('\n i is: %d\n',ind));
end
The problem is that I want each 'ind' value to be stored in an array.
for i=1:17
ind(i) = find(ismember(P,D(i)));
msgbox(sprintf('\n i is: %d\n',ind));
end
returns an error.
Is it possible assign find(ismember) to different entries of an array?
Thanks!
Edited:
My vectors P and D look as follows:
P = {'Fz' 'Fp1' 'Cz' 'T3' 'T4'}
D = {'T4' 'Cz' 'T3' 'Fp1' 'Fz'}
The error I'm getting at the moment is:
In an assignment A(:) = B, the number of elements in A and B must be the same.
You don't have to implement this yourself, ismember can already do it:
P = {'Fz' 'Fp1' 'Cz' 'T3' 'T4'};
D = {'T4' 'Cz' 'T3' 'Fp1' 'Fz'};
[~, ind] = ismember(D, P)
results in
ind =
5 3 4 2 1
But if you really want to do it yourself – your code basically works already
ind = zeros(size(D));
for i = 1 : numel(D)
ind(i) = find(ismember(P, D(i)));
end
and gives the same result.

Matlab: select subarrays from indexes matrix

I have a logical array B and a matrix A of size nx2 containing n couples of start/stop indexes
A= [start1, stop1; start2, stop2; start3, stop3];
How can I select the subarrays of array B based on start/stop couples contained in array A?
I'm doing it by:
for i=1:1:size(A,1)
B(A(i,1):A(i,2)) = true;
end
Is there any way of doing it in a more elegant way without using the for cycle (even conveniently rearranging array A)?
you can
n = numel(B);
iA = zeros( 1, n+1 ); %// +1 for boundary case
iA( A(:,1) ) = 1;
iA( A(:,2)+1 ) = -1;
iA(end) = []; %// discard boundary entry
B( cumsum(iA) > 0 ) = true;
Assumptions made
A(:,1) is always >= 1
A(:,2) is always <= n (number of elements in B)
the sections defined in A are non overlapping
If each stop is assured to be smaller than the next start (the index ranges don't overlap), another approach is
B(mod(sum(bsxfun(#le, 1:numel(B), [A(:,1)-1; A(:,2)])),2)>0) = true;

Resources