How to find a row in matrix containing closest values to given vector in Matlab - arrays

I am writing a function to find a row in matrix which is closest to given vector and given vector can be variable in size. For example if matrix size is by 4 and vector size is 3 then function will check the first three values form each row of matrix.
For comparison, I am calculating the distance of each row in matrix from given vector and then selecting the row which has minimum distance but I think this is not perfect solution because two different row can have same minimum distance from given vector.
I would like to know that is there any built in function available in matlab. I have already tried method ismember.

You can compute distances with pdist2, obtain the minimum, and then find all rows that have minimum distance:
vector = [1 3 2];
matrix = [2 1 2 2
1 3 3 4
0 0 0 0
5 4 3 2]; %// example data
dist = pdist2(vector, matrix(:,1:numel(vector)), 'euclidean'); %// compute distances
mindist = min(dist); %// minimum distance
result = find(dist==mindist); %// minimizing rows
Change 'euclidean' in pdist2 to use other distance definitions.
Depending on your definition of distance you could use bsxfun instead of pdist2. For example, for (squared) Euclidean distance,
dist = sum(bsxfun(#minus, vector, matrix(:,1:numel(vector))).^2, 2); %// squared distance

Related

Getting corresponding coordinates of a vectorized matrix

I have a matrix X of size n x m. I resized X to a vector a of length n x m.
How can I know "automatically" that the ith element in vector a corresponds to what element position (coordinates) in X?
I have written the following MATLAB code but I do not know how to continue.
X = rand(10,10);
[n,m] = size(X);
a = reshape(X, [n*m, 1]);
t = zeros(length(a),1);
for i = 1 : length(a)
t(i) = % I want to perform here the sum over the x and y coordinate values of the element in X
% that corresponds to the ith element in vector a.
end
Any help will be very appreciated.
That's what ind2sub does:
[row, col] = ind2sub([m n], i);
However, you may prefer to do it manually:
row = mod(i-1,m)+1;
col = floor((i-1)/m)+1;
This works because Matlab used column-major order for storing array elements. For example, in a 3×4 matrix the order in which the elements are stored in memory is as follows:
1 4 7 10
2 5 8 11
3 6 9 12
So the entry in the 2nd row, 3rd column is the 8th element in (column-major) linear order. When this matrix is reshaped into a vector (or into any other shape) this linear order is preserved. Therefore you can retrieve the original coordinates by divisions and modulus operations. Note also that, since Matlab's indexing is 1-based (as opposed to 0-based), the modulus operations need to be shifted by 1.

Compute the difference matrix between a matrix and another matrix in MATLAB

Given a matrix A in matlab with:
3 1
4 5
7 8
and another matrix B which could be referred to as some reference points (each row is reference point that is to be compared to each row of A),
1 1
1 2
I need to compute a matrix C, such that
4 5
25 18
85 72
Where each row of C is the difference (squared L2 norm) between each row of A and the rows of B. One possible way to do this in MATLAB is to first create a zero matrix C, C = zeros(5,2), and then use double for-loops to fill in the appropriate value. Is there any other efficient/simpler way in MATLAB?
Find the code snippet below
C = zeros(5,2)
for i = 1:rows
for j = 1:rows2
C(i,j) = (norm(A(i,:)-B(j,:)))^2
end
end
A solution similar to ThomasIsCoding's, but generalized to any number of dimensions (=columns). Thomas' answer requires A and B to have exactly 2 columns to use the complex representation. Here, we use a 3rd array dimension instead of complex values:
n = 3; % number of spatial dimensions for computing the L2 norm
A = 10*rand(20,n);
B = 10*rand(4,n);
C = sum((reshape(A,[],1,n) - reshape(B,1,[],n)).^2,3)
First we reshape A, such that its rows remain rows, but its columns are arranged along the 3rd array dimension. We reshape B similarly, but its rows become columns, and its columns are moved to the 3rd dimension. This arrangement of the first two dimensions match that of the output C.
Next we take the difference (using implicit singleton expansion, for older versions of MATLAB you'd need to use bsxfun), square, and sum along the 3rd dimension.
Maybe you can try bsxfun like below
A = [3,1; 4,5;7,8];
B = [1,1;1,2];
% you can first rewrite A and B in complex coordinates to simplify the computation, and then compute difference of two complex values
C = abs(bsxfun(#minus,A*[1;1j],transpose(B*[1;1j]))).^2;
and you will get
C =
4.0000 5.0000
25.0000 18.0000
85.0000 72.0000

How to find maximum value and location of each slice of 3D array in MATLAB?

What is the fastest way of calculating the maximum value, with it's corresponding index, of each 'slice' of a 3D array?
Say you have A with n slices (here I just made each slice 10 by 10, but this can be changed to any size):
A = rand(10,10,n);
You can reshape it to n-columns matrix, then take the maximum of each column:
[val,ind] = max(reshape(A,[],n),[],1);
The first output val will be an n-element vector with all the maximum values, and the second output ind will be their row index in the reshaped A.
Then you get the size of the slices:
sz = size(A);
and use it to find the row (r) and column (c) of each maximum element in each slice:
[r,c] = ind2sub(sz(1:2),ind)
So in this example (using rand and 10x10x6 array for A) you would get something like this at the end (but with different values):
val =
0.99861 0.98895 0.98681 0.99991 0.96057 0.99176
r =
9 7 3 8 2 9
c =
1 1 8 10 10 5
If you have a matrix A with n layers, you can apply max function in two steps to get a 1 x 1 x n matrix with max of each layer
A = rand(10,10,n);
layer_max = max(max(A,[],1),[],2); % 1 x 1 x n matrix, use squeeze to remove extra dims
layer_max = squeeze(layer_max);

How to build a binary matrix from sums

I have two decimal number variables, colSum and rowSum, using those I want to build a matrix of binary values based on those sums, the rowSum array variable is the result of adding all the 1's for each row, the same goes for colSum array.
So ,if you have
rowSum = [0,1,2]
colSum = [1,1,1]
you will have to build properly the following array
matrix = [
[0,0,0],
[0,0,1],
[1,1,0]
]
I'm using this method in PHP, that works for a 3x3 matrix, but not for a bigger one, like 8x8.
First ,fill all the 1's in the rows using the rowSum value.
Then ,try to find a wrong sum value of 2 columns, with a pivot I inter-change them (1 with a cero value) in the same row, until i get the correct value of colSum.
But it will not work because I need some control of the criteria to change the 1 and 0 in the same row for two columns...
This is the method I'm using.
Let's say we have this Matrix (N=3 -> NxN):
0 0 0
0 0 1
1 1 0
then we have the following arrays
R0 = {0,1,2} //--> result of sums of each rows: ( 0+0+0, 0+0+1 , 1+1+0 )
C0 = {1,1,1} // ->sums of each columns
Step 1
Create and fill a NxN array using as many 1's as R0(i) in each row:
0 0 0
1 0 0
1 1 0
compute sums of this new matrix now:
R1 = {0,1,2}
C1 = {2,1,0}
Step 2
Check if for all the elements of the column sums of the created matrix has the same value as C0 (origin)
for ( i=0, N-1) do
if C0(i)!=C1(i) then
ReplaceColumn(i)
end
end
To replace a column we have to dig inside the conditions.
C0(0) = 1 != C1(0) = 2
the first column sum does meet the condition to call the replace ,so
Step 3
Choose criteria for apply the branch & bound method and find the best row to change column that satisfy the global condition (all column sums).
The amount of changes for a difference between columns sums is:
|C0(i)-C1(i)|
for this example, |C0(0)-C1(0)| = 1 change.
Go back condition must be if the change generates a greater difference between the total sum of columns.
Σi,N(|C0(i)-C1(i)|)
So, could this method really work?
Is the goal to construct the matrix that satisfies the row and column sums or a matrix that satisfies them? It's not clear from the question, but if it's the former ("the" case) then it's not going to possible.
Suppose it were the case that you could uniquely represent any m × m matrix of bits in this way. Then consider the following hypothetical compression algorithm.
Take 22n bits of data
Treat it as 2n × 2n bits
To describe the data, use 2 × 2n row and column sums, each using at most log2(2n) = n bits
The data is compressed to 2 × n × 2n bits
Since 2 × n × 2n << 22n and this process could just keep being repeated, the supposition that you can uniquely represent any m × m matrix of bits by only its row and column sums is false.

Sort cell array base on the 2D value

I have a 3X3 cell array and each element store a (x,y) point.
The point are generate by random number from [0,1].
What I want to do is sort the cell array so that it looks like following
ex: 9 points
each circle is one 2D point
index:(1,1) in the left top corner and (3,3) to the right bottom corner as the usual array index
that is to ensure the topological order.
How do I do it?
Thank in advance.
for the example
pairs = [4 9 2 6 5 1 7 8 3; 9 6 2 1 3 8 7 4 5] (row 1 = x-values, row 2 = y-values))
what I want to do is put them in the cell array so that they can be connected by read lines like the image's topology.
The number of permutations is factorial(9), which is not terribly large. So a brute-froce approach is feasible: test all permutations for your desired conditions, and pick the first that is valid.
In the following I'm using a 2x3x3 array, instead of a 3x3 cell array containing length-2 vectors, because it's much easier that way.
N = 3;
data = rand(2,N,N);
permutations = perms(1:N^2); %// generate all permutations
for k = 1:numel(permutations)
dx = reshape(data(1,permutations(k,:)),N,N); %// permuted x data
dy = reshape(data(2,permutations(k,:)),N,N); %// permuted y data
if all(all(diff(dy,[],1)<0)) && all(all(diff(dx,[],2)>0)) %// solution found
disp(dx) %// display solution: x values
disp(dy) %// y values
break %// we only want one solution
end
end
Note that for some choices of data there may not be a solution.

Resources