Mahalanobis distance to find out nearest neighbor - matlab

Suppose I have some original data in a matrix a and measured data in matrix b. now i want to find out nearest point to matrix a 's element from matrix b.
The output should be ans = [1; 2; 3; 4;].
But when I try to do it, it does not give an output but error as a and b need to have same number of columns. How to solve this problem?
a = [1; 2; 3; 4];
b = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7];
k=1 ;
L = pdist2(a,b,'mahalanobis','smallest',K);

Related

program to choose 4 columns from 5 column matrix and find determinant in MATLAB

How can I make a program in MATLAB that will choose 4 columns out of a 5 column matrix and find the determinant from that new 4x4 matrix?
I tried setting each column as a vector with a variable:
a = [1; 2; 3; 4];
b = [5; 6; 7; 8]
c = [9; 0; 1; 2];
d = [3; 4; 5; 6];
e = [7; 8; 9; 0];
I need to make the program choose four out of the five vectors (in any order) and find the determinant.
Any help at all will be appreciated, thanks.
To control which columns the determinant is applied on, combine the columns into a single matrix, then choose the columns using indexing via cols
M = [a b c d e];
cols = [1 3 4 5];
det(M(:,cols))

How to create a matrix from a quarter matrix using symmetry

As an instance I have a matrix like this:
A = [1 2;
3 4]
The matrix A is the quarter of a matrix, the full matrix B can be obtained by mirroring A on the vertical and horizontal mirror axes. The resullt should be:
B = [1 2 2 1;
3 4 4 3;
3 4 4 3;
1 2 2 1]
How can I achive this in Matlab?
Edit: Is there a better way than
Q = [A fliplr(A)]
B = [Q ; flip(Q)]
?
You could do it in a single line, although "better" is slightly subjective
B = [A, fliplr(A); flipud(A), rot90(A,2)]

Rotate the rows of a matrix (like GAUSS function rotater)

I'm currently bringing some GAUSS code over to Matlab and I'm stuck trying to use the GAUSS "rotater" function.
The command reference entry for rotater says:
Purpose Rotates the rows of a matrix
Format y = rotater(x,r)
Input x: N x K matrix to be rotated. r: N x 1 or 1 x 1 matrix specifying the amount of rotation.
Output y: N x K rotated matrix.
Remarks The rotation is performed horizontally within each row of the matrix. A positive rotation value will cause the elements to move
to the right. A negative rotation will cause the elements to move to
the left. In either case, the elements that are pushed off the end of
the row will wrap around to the opposite end of the same row. If the rotation value is greater than or equal to the number of columns in x, then the rotation value will be calculated using (r % cols(x)).
Example 1
(I'm following Matlab's notation here, with straight brackets for matrices and a semicolon for a new ro)
If x = [1 2 3; 4 5 6], and r = [1; -1],then y = [3 1 2; 5 6 4]
Example 1
If x = [1 2 3; 4 5 6; 7 8 9; 10, 11, 12], and r = [0; 1; 2; 3], then y = [1 2 3; 6 4 5; 8 9 7; 10 11 12]
Maybe someone has found a function like that somewhere or can give me advice how to write it?
This can be done using bsxfun twice:
Compute rotated row indices by subtracting r with bsxfun and using mod. As usual, mod needs indices starting at 0, not 1. The rotated row indices are left as 0-based, because that's more convenient for step 2.
Get a linear index from columns and rotated rows, again using bsxfun. This linear index applied to x gives y:
Code:
[s1 s2] = size(x);
rows = mod(bsxfun(#plus, 1:s2, -r(:))-1, s2); % // step 1
y = x(bsxfun(#plus, rows*s1, (1:s1).')); %'// step 2
circshift is pretty close to what you're looking for except that 1) it works on columns rather than rows, and 2) it shifts the entire matrix by the same offset.
The first one is easy to fix, we just transpose. For the second one I haven't been able to find a vectorized approach, but in the meantime, here's a version with a for loop:
x = [1 2 3; 4 5 6; 7 8 9; 10 11 12]
r = [0 1 2 3]
B = x'
C = zeros(size(B));
for ii = 1:size(B,2)
C(:,ii) = circshift(B(:,ii),r(ii));
end
y = C'
The output is:
x =
1 2 3
4 5 6
7 8 9
10 11 12
r =
0 1 2 3
B =
1 4 7 10
2 5 8 11
3 6 9 12
y =
1 2 3
6 4 5
8 9 7
10 11 12
This can be done using a simple for loop to iterate over each row, and a function called 'circshift' from matlab.
I created a function the goes through each row and applies the appropriate shift to it. There may be more efficient ways to implement this, but this way works with your examples. I created a function
function rotated_arr = GaussRotate(input_array, rotation_vector)
[N,K] = size(input_array)
%creates array for return values
rotated_arr = zeros(N,K);
%if the rotation vector is a scalar
if (length(rotation_vector) == 1)
%replicate the value once for each row
rotation_vector = repmat(rotation_vector, [1,N]);
end
%if the rotation vector doesn't have as many entries as there are rows
%in the input array
if (length(rotation_vector) ~= N)
disp('ERROR GaussRotate: rotation_vector is the wrong size')
disp('if input_Array is NxK, rotation_vector must be Nx1 or 1x1')
return
end
%for each row
for idx=1:size(input_array,1)
%shift the row by the appropriate number of columns
%we use [0,shift] because we want to shift the columns, the row
%stays where it is (even though this is a 1xN at this point we
%still specify rows vs columns)
rotated_arr(idx,:) = circshift(input_array(idx,:),[0,rotation_vector(idx)]);
end
end
then simply called it with your examples
x = [1 2 3; 4 5 6];
r = [1; -1];
y = GaussRotate(x,r)
%produces [3 1 2; 5 6 4]
%I also made it support the 1x1 case
r = [-1]
%this will shift all elements one column to the left
y = GaussRotate(x,r)
%produces [2 3 1; 5 6 4]
x = [1 2 3; 4 5 6; 7 8 9; 10, 11, 12]
r = [0; 1; 2; 3]
y = GaussRotate(x,r)
%produces [1 2 3; 6 4 5; 8 9 7; 10 11 12]

shifting versions of a matrix

I have a m-by-n matrix and I want to shift each row elements k no. of times (" one resultant matrix for each one shift so a total of k matrices corresponding to each row shifts ")(k can be different for different rows and 0<=k<=n) and want to index all the resultant matrices corresponding to each individual shift.
Eg: I have the matrix: [1 2 3 4; 5 6 7 8; 2 3 4 5]. Now, say, I want to shift row1 by 2 times (i.e. k=2 for row1) and row2 by 3times (i.e. k=3 for row2) and want to index all the shifted versions of matrices (It is similar to combinatorics of rows but with limited and diffeent no. of shifts to each row).
Can someone help to write up the code? (please help to write the general code but not for the example I mentioned here)
I found the following question useful to some extent, but it won't solve my problem as my problem looks like a special case of this problem:
Matlab: How to get all the possible different matrices by shifting it's rows (Update: each row has a different step)
See if this works for you -
%// Input m-by-n matrix
A = rand(2,5) %// Edit this to your data
%// Initialize shifts, k for each row. The number of elements would be m.
sr = [2 3]; %// Edit this to your data
[m,n] = size(A); %// Get size
%// Get all the shits in one go
sr_ind = arrayfun(#(x) 0:x,sr,'un',0); %//'
shifts = allcomb(sr_ind{:},'matlab')'; %//'
for k1 = 1:size(shifts,2)
%// Get shift to be used for each row for each iteration
shift1 = shifts(:,k1);
%// Get circularly shifted column indices
t2 = mod(bsxfun(#minus,1:n,shift1),n);
t2(t2==0) = n;
%// Get the linear indices and use them to index into input to get the output
ind = bsxfun(#plus,[1:m]',(t2-1)*m); %//'
all_matrices = A(ind) %// outputs
end
Please note that this code uses MATLAB file-exchange code allcomb.
If your problem in reality is not more complex than what you showed us, it can be done by a double loop. However, i don't like my solution, because you would need another nested loop for each row you want to shift. Also it generates all shift-combinations from your given k-numbers, so it has alot of overhead. But this can be a start:
% input
m = [1 2 3 4; 5 6 7 8; 2 3 4 5];
shift_times = {0:2, 0:3}; % 2 times for row 1, 3 times for row 2
% desird results
desired_matrices{1} = [4 1 2 3; 5 6 7 8; 2 3 4 5];
desired_matrices{2} = [3 4 1 2; 5 6 7 8; 2 3 4 5];
desired_matrices{3} = [1 2 3 4; 8 5 6 7; 2 3 4 5];
desired_matrices{4} = [4 1 2 3; 8 5 6 7; 2 3 4 5];
desired_matrices{5} = [3 4 1 2; 8 5 6 7; 2 3 4 5];
% info needed:
[rows, cols] = size(m);
count = 0;
% make all shift combinations
for shift1 = shift_times{1}
% shift row 1
m_shifted = m;
idx_shifted = [circshift([1:cols]',shift1)]';
m_shifted(1, :) = m_shifted(1, idx_shifted);
for shift2 = shift_times{2}
% shift row 2
idx_shifted = [circshift([1:cols]',shift2)]';
m_shifted(2, :) = m_shifted(r_s, idx_shifted);
% store them
store{shift1+1, shift2+1} = m_shifted;
end
end
% store{i+1, j+1} stores row 1 shifted by i and row 2 shifted by j
% example
all(all(store{2,1} == desired_matrices{1})) % row1: 1, row2: 0
all(all(store{2,2} == desired_matrices{4})) % row1: 1, row2: 1
all(all(store{3,2} == desired_matrices{5})) % row1: 2, row2: 1

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