Maximal likelhood decoding in MATLAB - matlab

Given a matrix X of size (5,3), and a vector of y size (1,3), I need to calculate the Euclidean distance of vector y to all vectors in X and return to the minimal.
For example
X =
0.1338 0.0346 0.2961
0.5320 0.4681 0.6784
0.4484 0.5954 0.2847
0.1437 0.5310 0.3946
0.2854 0.0793 0.8621
y = 0.4484 0.5954 0.2847
So in that case, the minimal Euclidean distance of y is with row 3 in matrix Xsince it's the same.
I have made the code as below :
X = rand(5,3) %The matrix x
y = rand(1,3) %The vector y
[~, size_y] = size(y) %size of y
[size_x, ~] = size(X) %size of matrix x
min_distance = zeros(size_x,size_y); %Initialize the minimal distance
%% Calculate minimum distance square of vector y to every vector in x
for i = 1 : size_y
min_distance(:,i) = sum(abs(repmat(y(:,i),1,size_x) - X).^2,2);
end
min_distance_1 = min_distance;
[index, ~] = (min(min_distance_1,[],1));
results = index - 1;
The results of that code is mismatch error, however the index of row in matrix X which has the minimal Euclidean distance to vector y should be shown!!
Is there any mistake in code ? or how can I do that ?

I think there are a few things missing in your code. For the Euclidean distance there should be a root somewhere. Also index is the second return value, not the first and there is no reason for -1 and an index in matlab.
There is a build in function to calculate the euclidean distance called norm(). For your case where you want to calculate the distance to each vector there is a special vecnorm() thats fits perfectly.
differences = X-y
%you dont need repmat but keep it if it helps your understanding of the code
distances = vecnorm(differences,2,2)
%the first 2 is for 2-norm, which is Euclidean distance
%the second 2 for row-wise calculation
[~,index]= min(distances)

Related

how to calculate Weighted Averaging and distances in Octave

I have a set of data (100*3) which are (x,y,z). I need to calculate the 2nd order polynomial interpolation(it have been done) and weighted averaging.
I have the below code now. I am now trying to calculate weighted averaging with the attached formulas [enter image description here][1]. I need to first find out all the distance(d) between those 100 data and (50,50), then find the 5 nearest points. Secondly, calculate weighting(w). finally, calculate the Z. How can I calculate those data in Octave? Thank you.
[1]: https://i.stack.imgur.com/TMbP6.png
pkg load io
data = xlsread('data.xlsx');
## categorize the data
x = data(:,1);
y = data(:,2);
z = data(:,3);
## 2nd order polynomial interpolation
## Find polynomial coefficient
A = [ones(size(data,1),1) x y x.*y x.^2 y.^2];
a = pinv(A)*z;
## interpolation
grid_x = [0:2:100]';
grid_y = grid_x;
grid_z = zeros(size(grid_x,1), size(grid_x,1));
for i1 = 1:size(grid_x,1)
for i2 = 1:size(grid_y, 1)
A = [1 grid_x(i1) grid_y(i2) grid_x(i1).*grid_y(i2) grid_x(i1).^2 grid_y(i2).^2];
grid_z(i1, i2) = A*a;
endfor
end ```
You could use distance formula d2=(Xi-2)2+(Yi-2)2 to find distance where X and Y are the coordinate of the new interpolated point; and xi and yi are the
coordinate of the i, and then select the 5 nearest point. For Weight averaging, you could use w=1/d2.

Storing coordinates in Matlab and calculating Euclidean distance

I want to store a randomly generated set of co-ordinates in Matlab using a 2D array which should look like this
array = X Y
t1 x1 y1
t2 x2 y2
t3 x3 y3
... ...
tn xn yn
where ti is the i-th point in a 2D plane and has co-ordinates (xi,yi)
After creating this array, I want to calculate the Euclidean distance between ti and tj for all 1≤i,j≤n. How can this be achieved in Matlab?
N = 10; % # of points
X = rand(N, 1); % random coordinates
Y = rand(N, 1);
[X1, X2] = meshgrid(X);
[Y1, Y2] = meshgrid(Y);
d = sqrt((X1-X2).^2 + (Y1-Y2).^2); % pairwise distance in NxN, diag 0
The upper or lower triangle should contain the distance from
pdist([X Y]) % vector, not a matrix
You can use bsxfun to replicate operations over arrays.
N = 10;
p = rand(N,2); % coordinates
d = sqrt(bsxfun(#minus,p(:,1),p(:,1)').^2+bsxfun(#minus,p(:,2),p(:,2)').^2);
The first bsxfun replicates the X coords in p(:,1) and p(:,1)' into NxN matrices by expanding the singleton dimension and the result is the subtraction of these matrices. Similarly, the second bsxfun. The rest is just array operations to square, sum and square root.
If you happen to have the statistics toolbox you can use pdist, but this gives a row vector corresponding to the lower triangle of d.

Store vector values (x,y,z) in a matrix in a for loop. MATLAB

I wanted to create a matrix (A) that is flexible on size depending on how many data are available in a for loop. My code goes like this.
%Calculate x,y,z values
for i = 1:100
Vx = equation that will solve x values;
Vy = equation that will solve y values;
Vz = equation that will solve z values;
A = [Vx, Vy, Vz];
end
I would like matrix A to have a size of nx3, where n is any number of rows arrived by the calculation of x y z. In other words at after the for loop I would like to have matrix A with size n x 3.

' vectors must be the same length' error

I've got a 250 x 250 image, I want to have a scatter plot of the intensity of every pixel and its nearest neighborhood. This is my code:
I = imread(image);
i = [1,249];
j = [1,250];
X = I(i,j);
Y = I(i+1,j);
scatter(X,Y);
why do I get the " X and Y vectors must be the same length" error? They are the same length !
Because scatter(X, Y) is only used for vectors, not matrix. In your example, both X and Y are 2x2 matrices, not vectors.
From its documentation:
scatter(X,Y) displays circles at the locations specified by the vectors X and Y. This type of graph is also known as a bubble plot.
Edit: if you want to plot matrix, use plotmatrix() instead:
plotmatrix(X,Y)
Scatter(X,Y) is used only for vectors as herohuyongtao correctly mentioned. You could try to do the following:
m = 250;
X = I(m+1:end);
Y = I(1:end-m);
scatter(X,Y);
You convert your image matrix I into a vector X while ignoring the first column and in a vector Y while ignoring the last column. X(n) is thus the neighbour of Y(n) on the right side.
I hope this helps!

Ellipse around the data in MATLAB

I would like to reproduce the following figure in MATLAB:
There are two classes of points with X and Y coordinates. I'd like to surround each class with an ellipse with one parameter of standard deviation, which determine how far the ellipse will go along the axis.
The figure was created with another software and I don't exactly understand how it calculates the ellipse.
Here is the data I'm using for this figure. The 1st column is class, 2nd - X, 3rd - Y. I can use gscatter to draw the points itself.
A = [
0 0.89287 1.54987
0 0.69933 1.81970
0 0.84022 1.28598
0 0.79523 1.16012
0 0.61266 1.12835
0 0.39950 0.37942
0 0.54807 1.66173
0 0.50882 1.43175
0 0.68840 1.58589
0 0.59572 1.29311
1 1.00787 1.09905
1 1.23724 0.98834
1 1.02175 0.67245
1 0.88458 0.36003
1 0.66582 1.22097
1 1.24408 0.59735
1 1.03421 0.88595
1 1.66279 0.84183
];
gscatter(A(:,2),A(:,3),A(:,1))
FYI, here is the SO question on how to draw ellipse. So, we just need to know all the parameters to draw it.
Update:
I agree that the center can be calculated as the means of X and Y coordinates. Probably I have to use principal component analysis (PRINCOMP) for each class to determine the angle and shape. Still thinking...
Consider the code:
%# generate data
num = 50;
X = [ mvnrnd([0.5 1.5], [0.025 0.03 ; 0.03 0.16], num) ; ...
mvnrnd([1 1], [0.09 -0.01 ; -0.01 0.08], num) ];
G = [1*ones(num,1) ; 2*ones(num,1)];
gscatter(X(:,1), X(:,2), G)
axis equal, hold on
for k=1:2
%# indices of points in this group
idx = ( G == k );
%# substract mean
Mu = mean( X(idx,:) );
X0 = bsxfun(#minus, X(idx,:), Mu);
%# eigen decomposition [sorted by eigen values]
[V D] = eig( X0'*X0 ./ (sum(idx)-1) ); %#' cov(X0)
[D order] = sort(diag(D), 'descend');
D = diag(D);
V = V(:, order);
t = linspace(0,2*pi,100);
e = [cos(t) ; sin(t)]; %# unit circle
VV = V*sqrt(D); %# scale eigenvectors
e = bsxfun(#plus, VV*e, Mu'); %#' project circle back to orig space
%# plot cov and major/minor axes
plot(e(1,:), e(2,:), 'Color','k');
%#quiver(Mu(1),Mu(2), VV(1,1),VV(2,1), 'Color','k')
%#quiver(Mu(1),Mu(2), VV(1,2),VV(2,2), 'Color','k')
end
EDIT
If you want the ellipse to represent a specific level of standard deviation, the correct way of doing is by scaling the covariance matrix:
STD = 2; %# 2 standard deviations
conf = 2*normcdf(STD)-1; %# covers around 95% of population
scale = chi2inv(conf,2); %# inverse chi-squared with dof=#dimensions
Cov = cov(X0) * scale;
[V D] = eig(Cov);
I'd try the following approach:
Calculate the x-y centroid for the center of the ellipse (x,y in the linked question)
Calculate the linear regression fit line to get the orientation of the ellipse's major axis (angle)
Calculate the standard deviation in the x and y axes
Translate the x-y standard deviations so they're orthogonal to the fit line (a,b)
I'll assume there is only one set of points given in a single matrix, e.g.
B = A(1:10,2:3);
you can reproduce this procedure for each data set.
Compute the center of the ellipsoid, which is the mean of the points. Matlab function: mean
Center your data. Matlab function bsxfun
Compute the principal axis of the ellipsoid and their respective magnitude. Matlab function: eig
The successive steps are illustrated below:
Center = mean(B,1);
Centered_data = bsxfun(#minus,B,Center);
[AX,MAG] = eig(Centered_data' * Centered_data);
The columns of AX contain the vectors describing the principal axis of the ellipsoid while the diagonal of MAG contains information on their magnitude.
To plot the ellipsoid, scale each principal axis with the square root of its magnitude.