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 Exchange에서 Problem-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