K Means Algorithm in MATLAB - Explain the Cluster Label Assignment Step - matlab

I have a Matlab code from my class in which the professor does the step of assigning each data point to the nearest cluster using this code where c is the centroids matrix and x is the data matrix.
% norm squared of the centroids;
c2 = sum(c.^2, 1);
% For each data point x, computer min_j -2 * x' * c_j + c_j^2;
% Note that here is implemented as max, so the difference is negated.
tmpdiff = bsxfun(#minus, 2*x'*c, c2);
[val, labels] = max(tmpdiff, [], 2);
I am not sure how this is equivalent to the algorithm definition of this step in which the cluster assignment is done through
% For every centroid j and for every data point x_i
labels(i) = `argmin||x_i - c_j||^2`
Can anyone please explain to me how this works, essentially how computing
min_j -2 * x' * c_j + c_j^2
is equivalent to
argmin||x_i - c_j||^2

If we have a triangle such that the length of its sides is a, b, c, then
we know that (from the law of cosines)
a^2=c^2+b^2-2bc*cos(alpha)
where alpha is the angle between the side with size b and the size with size c.
Now, consider the triangle made of the three vertices x, c_j and O (the origin of R^n). Writing theta the angle between x and c, we have
argmin_j||x-c_j||^2
=argmin_j (||x||^2+||c_j||^2 - 2*||x||* ||c_j|| * cos(theta) )
which is equal to
argmin_j(||x||^2 + ||c||^2 - 2x^t c_j)
Now, remember that x is constant in this minimization, so the last equation is just equal to
argmin_j(||c_j||^2 - 2 x^t c_j)
which is the equation you minimize in your code.

Related

discretise domain of x and y with 0.01 separation between points

I am looking to calculate an array from a formula using x and y variables, the domain of x is (0,50) and y is (0,30) . I am asked to discretise the domain of x and y with 0.01 separation between points, then compute L(x,y) (which I have a formula for)(This will be points of a graph, ultimately I'm looking for the min lengths between points)
I'm not sure what I need to define in my script because if I define x and y as arrays with 0.01 separation they end up being uneven and unable to calculate as the arrays are uneven
%change these values for A, B and C positions
Ax=10;
Ay=5;
Bx=15;
By=25;
Cx=40;
Cy=10;
x = 0:0.01:50; % Array of values for x from 0-50 spaced at 0.01
y = 0:0.01:30; % Array of values for y from 0-30 spaced at 0.01
%length of point P from A, B and C and display
Lpa=sqrt((Ax-x).^2+(Ay-y).^2);
Lpb=sqrt((Bx-x).^2+(By-y).^2);
Lpc=sqrt((Cx-x).^2+(Cy-y).^2);
L=Lpa+Lpb+Lpc
I am getting an error telling me the two matrix are not even which makes sense to not work but I'm not sure how to define a matrix that will result in the minimum x and y values I am after.
Any help would be greatly appreciated.
You want to calculate L for each possible pair of x and y. In other words, for the first value of x = 0, you will calculate L for all y values from 0 to 30, then for next value of x = 0.01, you will do the same and so on.
MATLAB has a really cool function called meshgrid to create a matrix for every pair of x and y. So after generating x and y, change your code to the following to get a 2D matrix for L -
[X, Y] = meshgrid(x, y)
%length of point P from A, B and C and display
Lpa = sqrt((Ax - X).^2 + (Ay - Y).^2);
Lpb = sqrt((Bx - X).^2 + (By - Y).^2);
Lpc = sqrt((Cx - X).^2 + (Cy - Y).^2);
L = Lpa + Lpb + Lpc

Coordinate from 2 vectors

All,
Suppose I have two vectors U and V with 2 units and 1 unit length, respectively as shown in the sketch. The vector U is rotated by angle theta.
There are, at least two possible cases whereby vector U can go "up" or "down" as shown in the sketch.
My question is, having the above dataset is it possible to have a generic formula that can be transferred into Matlab to get the coordinate of point M?
the length of the vector U and V and angle theta are arbitrary.
Thank you!
There is a more efficient solution.
The coordinates of the endpoints of U are given by:
(U * cos(theta), U * sin(theta))
For any vector (x, y) the clockwise perpendicular direction (i.e. the second diagram "down") is (y, -x), and those of the anti-clockwise direction are minus these. Therefore the coordinates of M are given by:
Anti-clockwise ("up"): (U * cos(theta) - M * sin(theta), U * sin(theta) + M * cos(theta))
Clockwise ("down"): (U * cos(theta) + M * sin(theta), U * sin(theta) - M * cos(theta))
No need for calls to arctan or sqrt which are both very costly. Also you can compute sin/cos just once and use the results for both components.
From Pythogoras we know that
M = sqrt(U^2 + V^2)
angle between M and U is
alpha = arctan(V/U)
So then you know that the x- and y-coordinates for M are:
the "up" case:
M = (sqrt(U^2 + V^2)*cos(theta + sign(cosd(theta))*arctan(V/U)), sqrt(U^2 + V^2)*sin(theta + sign(cosd(theta))*arctan(V/U)))
the "down" case:
M = (sqrt(U^2 + V^2)*cos(theta - sign(cosd(theta))*arctan(V/U)), sqrt(U^2 + V^2)*sin(theta - sign(cosd(theta))*arctan(V/U)))
A second way to calculate this is to look add the length of U and V in the x and y direction, and sum them.
The coordinates of U are:
(Ucos(theta), Usin(theta))
To this coordinates we must add/substract the x-and y-coordinates of V. The length of V along x and y is:
(abs(sin(theta)), abs(cos(theta))
Whether one should add or substract these from U is dependent on theta. In general we can write Vup and Vdown as
Vup = (V*sign(-cos(theta))sin(theta), Vsign(cos(theta))*cos(theta))
Vdown = (V*sign(cos(theta))sin(theta), Vsign(-cos(theta))*cos(theta))
then we can alway add U to Vup and Vdown. Finally
Mup = U + Vup
Mdown = U + Vdown
Just another compact solution
theta = 30;
L = 2; % norm of U vector
U = L*[cosd(theta) ; sind(theta)];
Vup = [-U(2) ; U(1)] / L; % Normal vectors, unit length
Vdown = [U(2) ; -U(1)] / L;
Mup = U + Vup; % Two possible values of M
Mdown = U + Vdown;
% Bonus plot
figure
plot([0 U(1)] , [0 U(2)] , 'k-')
hold on; axis equal;
plot([0 Vup(1)]+U(1) , [0 Vup(2)]+U(2) , 'r-')
plot([0 Vdown(1)]+U(1) , [0 Vdown(2)]+U(2) , 'r-')
text(Mup(1),Mup(2),'M_u_p')
text(Mdown(1),Mdown(2),'M_d_o_w_n')
You can exploit the properties of the cross product of Uinit and Urot. The sign of the product will inform you on the orientation of the resulting vector.
Supposing that the origin is O(0,0), your initial vector is Uinit(x1,y1) and your final vector is Urot(x2,y2). Also M(x,y) can be calculated easily.
If you want to filter the rotated vectors Urot that ended up 'above' or 'below' M compared to the previous orientation of your triangle, you can take the following cross products:
M cross Uinit and M cross Urot.
If their sign is the same then the resulting rotated vector didn't cross the line OM and the opposite if the sign is different.

Matlab - linear regression - y-intercept by adding one column of ones

I try to understand on the following link linear regression the computing of coefficients beta0 and beta1 for the relation y = beta0 + beta1 x.
I understand the first computing of beta1 which is actually a simple least-squares regression, but with only one paramater to find (the slope coefficient) ?
In the example of "accidents", Why do they append a colum of ones to x array to compute the 2 coefficients :
X = [ones(length(x),1) x];
b = X\y
result :
b =
1.0e+02 *
1.427120171726537
0.000001256394274
what is the underlying calculation with this column of ones ?
If anyone could explain to me.
This is more like comment. But I am not allowed to do that, so writing as an answer.
They are adding column of ones to make it suitable for matrix multiplication. You have y = beta0 + beta1*x. In matrix multiplication form, it can be written as : y = [1 x]* [beta0 beta1]'. Please note transpose sign on beta matrix.
For reasons unkonwn to me, vectorization of variables is encouraged in Matlab and R. As per my knowledge, vectorization is expected to reduce resource consumption.
Ones are often added to introduce "bias". In your case, try visualizing this equation:
y = w1 * x + c
The ones are added to represent another input, but which is always one.
y = w1 * x1 + c * x2(which is 1)
So, to model equations with constants(bias) in them, ones are added to the input.
Because in the equation y = beta0 + beta1 * x, beta0 is implicitly multiplied by 1.
Put another way consider the ith (x,y) pair:
y[i] = beta0 + beta1 * x[i]
= beta0 * 1 + beta1 * x[i]
That 1 that is multiplying beta0 for any i is where the ones vector is coming from.

Finding the point of intersection on a 3D line perpendicular to a target point

I have a line and a point and I wanted to find a point (x,y,z) on the line that is 90 degrees or perpendicular if I were to draw a line from this point of intersection with another point.
So far I can create a line with this code and i have another code that calculates angle between three points, but that doesn't really apply here:
a = [1 1 2]; %line
b = [20 28 90]; % line
c = [50 30 67]; %point
ab = b - a;
n = max(abs(ab)) + 1;
s = repmat(linspace(0, 1, n)', 1, 3);
for d = 1:3
s(:, d) = s(:, d) * ab(d) + a(d);
end
s = round(s);
Z = 100;
N = 100;
X = zeros(N, N, Z);
X(sub2ind(size(X), s(:, 1), s(:, 2), s(:, 3))) = 1;
x = c(:,1);
clf
plot3(s(:, 1), s(:, 2), s(:, 3), 'r.-')
axis(N * [0 1 0 1 0 1])
grid on
This will require a bit of mathematics to determine that analytically. By "90 degrees", I'm assuming you want to find the point on this 3D line that would be perpendicular to this line if you extended a line from this point of intersection to the desired point.
I'm assuming the two points a and b denote the coordinates in 3D space where a line can join them and that c is the point of interest. Here's a better diagram of what I'm talking about:
Source: MathWorld
In your case, x1 and x2 denote a and b in your code and x0 denotes c. The distance d would be the distance on the line that would allow the point to be perpendicular to this line if you extended a line from the point of intersection to the point c.
You can define a parametric equation that describes the line between x1 and x2 like so:
A point on this line between x1 and x2 can be described by taking each of the (x,y,z) values for x1 and x2 and writing it in the above parametric form and varying the parameter t, which goes from [0,1]. Therefore t=0 would give you the first point x1 or a and t=1 would give you the second point x2 or b. Any value of t between [0,1] would give you a point along the line. The objective is to find the value t that would minimize the distance from x0 or c to this line. Like I said before, we all know from geometry that the smallest distance from a point to a line would make the angle of intersection perpendicular / 90 degrees if you extended a line from this point of intersection to the point x0 or c.
Therefore, all you have to do is find this value of t, then substitute this into the above parametric equation to find your desired point. In other words, we want to minimize the distance between the point and the line, and the distance can be described like so:
To find the minimum distance, you'd find the parameter t that minimized the above equation by finding the derivative with respect to t and setting it equal to 0. Logistically, you would take the square root of the equation so that you would be minimizing the distance, and not the distance squared. However, it's actually easier to minimize the distance squared, which is why the equation above is represented like so. It makes sense because if you minimize the distance squared.... the distance would also be minimized as you'd simply just place a square root on the answer to get what you asked for. Eliminating the square root from the equation would make calculating the derivative easier.
If you do that, and solve for t, we get this equation:
Therefore, find the difference between a and c, take this with the dot product with the difference between b and a, then divide this by the magnitude squared of the difference between b and a. This solves for t, and then you'd substitute this into the above parametric equation to find your point.
In MATLAB code, it could look something like this:
a = [1 1 2]; %line - x1
b = [20 28 90]; % line - x2
c = [50 30 67]; %point - x0
ab = b - a; %// Find x2 - x1
%// -(x1 - x0).(x2 - x1) / (|x2 - x1|^2)
t = -(a - c)*(ab.') / (ab*ab.'); %// Calculate t
%// Find point of intersection
Xinter = a + (b - a)*t;
The code for t I took advantage of using matrix multiplication. The dot product can be found by multiplying a row array by a column array and in a similar fashion, if the row array and column array have the same coefficients, this results in the magnitude squared of a vector.
For your example, we get:
Xinter =
16.9889 23.7211 76.0539
To show that this is right, let's plot the line, and the point and the point of intersection:
The code to produce the above figure is:
figure;
%// Plot line
plot3([a(1) b(1)], [a(2) b(2)], [a(3) b(3)]);
hold on;
%// Plot point of interest in red
plot3(c(1), c(2), c(3), 'r.');
%// Plot intersection point in green
plot3(Xinter(1), Xinter(2), Xinter(3), 'g.');
%// Plot line from intersection point to point of interest in black
plot3([c(1) Xinter(1)], [c(2) Xinter(2)], [c(3) Xinter(3)], 'k');
%// Turn on a grid
grid;

calculate integration in matlab for environmental physics data series

The following diagram is a schematic of a lake, and the equation illustrates how to calculate the effective heat flux of a lake.
where S is a vector of surface fluxes, q is short wave radiation, h is depth of the mixed layer, and z is the depth of the lake. For example:
q0 = 400+(1-400).*rand(100,1); % This is the short wave radiation
kd = 0.8; % extinction coefficient
h = 10; % depth of the surface mixed layer
for i = 1:length(q0); % loop for calculating short wave radiation at depth h
qh(i) = q0(i).*exp(-kd*h); % here, qh is calculated according to the Lambert Beer law
end
given
dz = 0.5
and z varies from 0 (surface) to depth h in increments of dz i.e.
z = 0:dz:h
how would I calculate the last portion of this equation in matlab i.e. how to calculate q at depth z between the surface and h? which is expressed here as an integral?
Apologies if this should be on another one of the stack overflow forums but it seems more related to programming than pure physics or maths questions.
To integrate this correctly, you will need compute all values of q(z) in the range [0, h]. If q0 and qh are N-by-1 column vectors, this means that q should be an N-by-M matrix, where M is the number of sample points in the range [0, h].
First, lets define z properly:
z = linspace(0, h, 200); %// M=200, but it's an arbitrary number to your choosing
The computation of q can be reduced to:
q = q0 * exp(-kd * z);
and qh actually equals to the final column of q, i.e q(:, end).
The integral itself can be approximated to a sum and computed using sum:
dz = z(2) - z(1);
I = sum(q, 2) * dz;
P.S.
Since q(z) = e(-kd ·z), it's simple enough for you to compute the integral analytically:
I = q0 * (1 - exp(-kd * h)) / kd;