cos() between vectors in matrix Optimization

Hello all,
I'm writing to ask for some help optimizing the following code. I'm taking a matrix, S, into my function, and I want to collect the cosine of the angle between each pair of columns in S into Dc, as you can see, I have naively done this with two for loops, what I want to know is if there is a way of doing this that takes advantage of the matrix operations of MATLAB, so that it runs faster. I am currently testing on a small(ish) matrix, Dc ends up on the order of 1300x1300, but I hope to expand the code to operate on larger matrices, between 10 and 15 times this size.
Any pointers would be much appreciated.
Dc = zeros(size(S,2));
for i = 1:length(S)
for j = 1:length(S)
Dc(i,j) = (S(:,i)' * S(:,j))/(norm(S(:,i))*norm(S(:,j)));
end
end

 採用された回答

Roger Stafford
Roger Stafford 2013 年 12 月 25 日

1 投票

This might be faster. It avoids repetition in computing norms.
Dc = S'*S;
N = sqrt(diag(Dc));
Dc = Dc./(N*N');

4 件のコメント

Matthew
Matthew 2013 年 12 月 25 日
I appreciate the response, but your code doesn't do the same thing that mine does.
Run them on a 3x3 S matrix, and you'll see that the Dc that are created are not the same.
Roger Stafford
Roger Stafford 2013 年 12 月 25 日
編集済み: Roger Stafford 2013 年 12 月 25 日
I have done that and get the same answer for both methods within round-off error. What result would you get on the following?
format long
S = magic(3);
Dc = zeros(size(S,2));
for i = 1:length(S)
for j = 1:length(S)
Dc(i,j) = (S(:,i)'*S(:,j))/(norm(S(:,i))*norm(S(:,j)));
end
end
Dc1 = Dc;
Dc = S'*S;
N = sqrt(diag(Dc));
Dc = Dc./(N*N');
Dc2 = Dc;
Dc1 =
1.00000000000000 0.60459579105879 0.86516853932584
0.60459579105879 1.00000000000000 0.60459579105879
0.86516853932584 0.60459579105879 1.00000000000000
Dc2 =
1.00000000000000 0.60459579105879 0.86516853932584
0.60459579105879 1.00000000000000 0.60459579105879
0.86516853932584 0.60459579105879 1.00000000000000
I repeated the test for S = randn(25,32) and again the maximum difference between the two results was 1.332267629550188e-15, well within expected round-off error.
There is one way you can get significantly different results. You have written "for i = 1:length(S)" instead of "for i = 1:size(S,2)" and similarly for the j-loop, which will give you an error message if there are more rows than columns in S. Remember, 'length' is the maximum of the number of rows and of the number of columns.
(Corrected)
Matt J
Matt J 2013 年 12 月 25 日
編集済み: Matt J 2013 年 12 月 25 日
Using DNorm2, you can eliminate the outer product N*N',
Dc = bsxfun(@rdivide,S, DNorm2(S,1));
Dc = Dc'*Dc;
Matthew
Matthew 2013 年 12 月 25 日
Thank you Rodger.
The size v length was my main issue. I was testing with some square matricies, and some rectangular matricies.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeProblem-Based Optimization Setup についてさらに検索

質問済み:

2013 年 12 月 25 日

コメント済み:

2013 年 12 月 25 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by