Reputation: 25
I have a matrix A
that contains 24 values for each day of the year (one value for each hour). Each column of A
is a different day and each day has 24 rows worth of data (A
is 24-by-365). I want to compare each day to each other by comparing the hour data of each day. To do this, I take one column of data and compare it to the next column. I take the difference of each hour's data in the two columns and then square and sum them to get a single value indicating how similar the two days are. I then do this with every possible combination of days, creating a 365-by-365 matrix, d
, indicating how similar each day is to each other day. For example, element d(20,100)
contains a value indicating how similar the 20th day of the year is to the 100th. The code is working, but it is quite slow and I would like to be able to vectorize it. Help would be greatly appreciated.
for j=1:365
for k=1:365
d(j,k)=sqrt(sum((A(:,j)-A(:,k)).^2));
end
end
Upvotes: 1
Views: 336
Reputation: 114986
You can't beat horchler's answer, but for completeness here's how this can be done using bsxfun
d = bsxfun(@minus, permute(A, [3 2 1]), permute(A, [2 1 3]));
d = sqrt( sum( d.^2, 3 ) );
Another nice way of doing this is using the fact that || x - y || = sqrt(||x||^2-2< x,y >+||y||^2)
. Therefore
n = sum(A.^2, 1); % norm of each vector
b = bsxfun(@plus, n, n') - 2 * A' * A;
Upvotes: 4
Reputation: 18504
Pairwise Euclidean distance using pdist
, which does the heavy-lifting in C, and squareform
to create the distance matrix:
d = squareform(pdist(A.'));
If you need this to be even faster (365-by-365 is not very big though), see my answer here or try this File Exchange program.
Upvotes: 5