Matlab, intersection of two vectors - matlab

i want to determinate the positions when 2 vectors are intersected without using repetitive operations. For example
A = [ 2 2 3 4 5]
B = [ 2 3 3 8 5]
And the output will be
R = [1 3 5].

You can simply use find with a logical matrix:
A = [2 2 3 4 5];
B = [2 3 3 8 5];
R = find(A == B)
1 3 5
The expression A == B will create a logical matrix where an element is true (1) if the element in A is equal to the element in B and false (0) if they are not equal. Then find will identify the positions in this logical matrix where the values are true.

Related

How to creat a four dimentional (from a vector) matrix and reset it's 'lower triangle'

I am trying to get a 4 dimentional matrix out of a vector and then reset it's
'lower triangel'.
for example, if my original vector is two dimentional: A = [1 2]' then I would like my initial matrix to be:
C(:,:,1,1) = [1*1*1*1 1*1*1*2 ; 1*1*2*1 1*1*2*2] = [ 1 2 ; 2 4]
C(:,:,2,1) = [2*1*1*1 2*1*1*2 ; 2*1*2*1 2*1*2*2] = [ 2 4 ; 4 8]
C(:,:,1,2) = [1*2*1*1 1*2*1*2 ; 1*2*2*1 1*2*2*2] = [ 2 4 ; 4 8]
C(:,:,2,2) = [2*2*1*1 2*2*1*2 ; 2*2*2*1 2*2*2*2] = [ 4 8 ; 8 16]
So C is:
C(:,:,1,1) = [ 1 2 ; 2 4] C(:,:,2,1) = [ 2 4 ; 4 8]
C(:,:,1,2) = [ 2 4 ; 4 8] C(:,:,2,2) = [ 4 8 ; 8 16]
and after reset I would like it to be:
C(:,:,1,1) = [ 1 2 ; 2 4] C(:,:,2,1) = [ 0 0 ; 0 0]
C(:,:,1,2) = [ 0 0 ; 4 8] C(:,:,2,2) = [ 0 0 ; 8 16]
shotrly, I want no rows repetitions.
I tried the following code:
A = [1 2]';
C = bsxfun(#times, permute(C, [4 3 2 1]), C*C');
disp('C before reset is:');
disp(C);
for k = 2:size(C, 4)
C(1:k-1,:,k) = 0;
end
disp('C after reset is:');
disp(C);
disp('The size of C is:');
disp(size(C));
But the output is:
BB before reset is:
(:,:,1,1) =
1 2
2 4
(:,:,1,2) =
2 4
4 8
C after reset is:
(:,:,1,1) =
1 2
2 4
(:,:,1,2) =
0 0
4 8
The size of BB is:
2 2 1 2
What did I miss?
I think I don't understand what is behind the line:
C = bsxfun(#times, permute(C, [4 3 2 1]), C*C');
what is the meaning of each number in the row [4 3 2 1]?
Thanks!
edit note: The matrix represents correlations between neurons. I am trying to look at the correlation structure of groups of 4 neurons. So, each 4 neurons sould only be measuresd once. I think that he matrix before reset contains 4! times, every group of 4, because they apear in all orders. I could leave it like this but I am think it might slow the program..
Permute exchanges dimensions, so for example
C = [1:3;4:6];
permute(C, [2 1])
Computes a simple transpose by swapping rows and columns. The [2 1] argument means that the 2st and 1st dimension of C are mapped to the 1st and 2nd dimension in the result. Each 'new' dimension is specified in order. So [3 2 1] would take the 3rd, 2nd and 1st dimensions to be the new 1st, 2nd and 3rd dimensions.
permute(C, [3 2 1])
ans =
ans(:,:,1) =
1 2 3
ans(:,:,2) =
4 5 6
Elements of C with row = 1 are found in where the 3rd dimension = 1 in the result. Similarly, elements of C with row = 2 are found where the 3rd dimension = 2 in the result.
Elements of C with column = 1 are still found where column = 1 in the result (and so on) as the column dimension was mapped to itself.
The rows of the result is the interesting dimension, it is singleton (i.e. there is only one row) as a result of C having no 3rd dimension.
Addressing the first part of your problem, the correct output for C can be obtained by
A = [1 2]'*[1 2];
C = bsxfun(#times, permute(A, [4,3,1,2]), A);
I would need more information on what you want the final behaviour to be ('resetting the lower triangle') as it is unclear to me what you desire.
A function that might be useful to you is the triu function which extracts upper triangular components of a matrix.

Finding the mean of more than one vector

I am tring to get the mean of three vectors but the mean function is not working.
Example:
A = [1 2 3 4 5];
B = [2 3 4 5 6];
C = [3 4 5 6 7];
V = mean(A,B,C); % should be [2 3 4 5 6] as each column is the some of the same column in A, B and C divided by three.
Any Help?
For a general case (row or column vector case), you can use this -
mean_vals = mean(cat(2,A(:),B(:),C(:)),2)

Got confused with a vector indexed by a matrix, in Matlab

The following codes runs in Matlab:
a = [1 2 3 4]
b = [ 1 2 3; 1 2 3; 1 2 3]
a(b)
The result of a(b) is a matrix:
[ 1 2 3; 1 2 3; 1 2 3]
Can anyone explain what happened here? Why a vector can be indexed by a matrix, how to interpret the result?
That's a very standard MATLAB operation that you're doing. When you have a vector or a matrix, you can provide another vector or matrix in order to access specific values. Accessing values in MATLAB is not just limited to single indices (i.e. A(1), A(2) and so on).
For example, what you have there is a vector of a = [1 2 3 4]. When you try to use b to access the vector, what you are essentially doing is a lookup. The output is basically the same size as b, and what you are doing is creating a matrix where there are 3 rows, and each element accesses the first, second and third element. Not only can you do this for a vector, but you can do this for a matrix as well.
Bear in mind that when you're doing this for a matrix, you access the elements in column major format. For example, supposing we had this matrix:
A = [1 2
3 4
5 6
7 8]
A(1) would be 1, A(2) would be 3, A(3) would be 5 and so on. You would start with the first column, and increasing indices will traverse down the first column. Once you hit the 5th index, it skips over to the next column. So A(5) would be 2, A(6) would be 4 and so on.
Here are some examples to further your understanding. Let's define a matrix A such that:
A = [5 1 3
7 8 0
4 6 2]
Here is some MATLAB code to strengthen your understanding for this kind of indexing:
A = [5 1 3; 7 8 0; 4 6 2]; % 3 x 3 matrix
B = [1 2 3 4];
C = A(B); % C should give [5 7 4 1]
D = [5 6 7; 1 2 3; 4 5 6];
E = A(D); % E should give [8 6 3; 5 7 4; 1 8 6]
F = [9 8; 7 6; 1 2];
G = A(F); % G should give [2 0; 3 6; 5 7]
As such, the output when you access elements this way is whatever the size of the vector or matrix that you specify as the argument.
In order to be complete, let's do this for a vector:
V = [-1 9 7 3 0 5]; % A 6 x 1 vector
B = [1 2 3 4];
C = V(B); % C should give [-1 9 7 3]
D = [1 3 5 2];
E = V(D); % E should give [-1 7 0 9]
F = [1 2; 4 5; 6 3];
G = V(F); % G should give [-1 9; 3 0; 5 7]
NB: You have to make sure that you are not providing indexes that would make the accessing out of bounds. For example if you tried to specify the index of 5 in your example, it would give you an error. Also, if you tried anything bigger than 9 in my example, it would also give you an error. There are 9 elements in that 3 x 3 matrix, so specifying a column major index of anything bigger than 9 will give you an out of bounds error.
Notice that the return value of a(b) is the same size as b.
a(b) simply takes each element of b, call it b(i,j), as an index and returns the outputs a(b(i,j)) as a matrix the same size as b. You should play around with other examples to get a more intuitive feel for this:
b = [4 4 4; 4 4 4];
a(b) % Will return [4 4 4; 4 4 4]
c = [5; 5];
a(c) % Will error as 5 is out of a's index range

Pairwise distance matrix containing strings

I need to calculate the pairwise distance between two matrix elements in a way that distance is equal to the number of binary differences between features/dimensions.
I want to do this with MATLAB codes without using a loop.
For example:
Assume I want to calculate the distance between instances in A and B:
A = [ 1 2 3 ; 2 3 4] % (two instances with three features)
B = [ 2 3 4 ; 2 5 6 ; 4 5 6] % (three instances with three features)
I need to calculate C, which would be a 2x3 matrix contain the distance of instances in A and B in a way that the distance between [1 3 3] and [2 3 4] would be 2: comparing the features, when a feature is equivalent, add 0 to distance and when they are dissimilar add 1 to distance.
So in this case,
C = [3 3 3; 0 2 3].
A and B may contain strings instead of numbers.
You can use bsxfun with #ne (not equal), followed by a sum to count the number of dissimilar features for an instance:
A = [1 2 3; 2 3 4];
B = [2 3 4; 2 5 6; 4 5 6];
C = squeeze(sum(bsxfun(#ne,A,permute(B,[3 2 1])),2))
C =
3 3 3
0 2 3
The above works by generating a logical array testing for equality of each feature for each instance pair via bsxfun(#ne,...). Then a sum is performed over dimension 2 to count the number of dissimilar features for each instance.
The function pdist2 with Hamming distance already does this for you:
pdist2(A,B,'hamming')
This gives the result as percentage of coordinates that differ. Since you want number instead of percentage, multiply by the number of columns:
pdist2(A,B,'hamming')*size(A,2)
ans =
3 3 3
0 2 3

Matlab - find function between matrix and cell array

I’ve a matrix A = (4*4) and a cell array B {4,1}. I’d like to find all the values of B in A, searching row by row and after I’d like to delete the correspondent column associated to this particular value. I’ve a problem using bsxfun o cellfun and find function with a matrix and a cell array. I‘ve tried to convert the cell array into a matrix but I don’t have more the exact correspondence.
For example:
A =
1 5 10 23
2 4 2 18
3 3 5 14
1 9 10 4
B =
1
2 4
3 3 14
1
To obtain:
C =
10
2
5
10
Thanks in advance,
L.
Here's how:
C = cellfun(#(x, y){sparse(1,find(ismember(x,y),numel(y)),true,1,size(A,2))}, ...
mat2cell(A, ones(size(A, 1), 1), size(A, 2)), B(:));
C = A(:, all(~vertcat(C{:})));
The cellfun is fed with two cell arrays: the first one contains the rows of A and second one is B. The anonymous function is the tricky part; it operates on a pair of two corresponding rows as follows:
It employs ismember to check which columns in A contain any of the elements in B.
It uses find to pick only the first N ones, with respect to the number of elements in the B.
It uses sparse as a fancy way of zeroing out the rest of the elements.
For your example it would look like this:
A = [1 5 10 23; 2 4 2 18; 3 3 5 14; 1 9 10 4];
B = {1; [2 4]; [3 3 14]; 1};
C = cellfun(#(x, y){sparse(1,find(ismember(x,y),numel(y)),true,1,size(A,2))}, ...
mat2cell(A, ones(size(A, 1), 1), size(A, 2)), B(:));
which yields:
C =
{
[1 0 0 0]
[1 1 0 0]
[1 1 0 1]
[1 0 0 0]
}
After that, it's a simple matter of logical indexing to pick the resulting columns:
C = A(:, all(~vertcat(C{:})));
which in this case should be:
C =
10
2
5
10