2013-08-02 52 views
0

我想要獲得大陣列中每個向量之間的角度(1896378x4 -EDIT:這意味着我需要1.7981e+12角度...太大,但如果有優化代碼的空間,請告訴我)。這太慢了 - 我還沒有看到它完成。下面是步驟,優化我已經採取了:matlab - 優化獲得每個向量與大陣列中所有其他向量之間的角度

首先,在邏輯上是我(我想)要(只使用Bt=rand(N,4)用於測試):

[ro,col]=size(Bt); 
    angbtwn = zeros(ro-1); %too long to compute!! total non-zero = ro*(ro-1)/2 
    count=1; 
    for ii=1:ro-1 
     for jj=ii+1:ro 
      angbtwn(count) = atan2(norm(cross(Bt(ii,1:3),Bt(jj,1:3))), dot(Bt(ii,1:3),Bt(jj,1:3))).*180/pi; 
      count=count+1; 
     end 
    end

所以,我雖然我想嘗試與它矢量化和擺脫非內置功能:

[ro,col]=size(Bt); 
% angbtwn = zeros(ro-1); %TOO LONG! 
for ii=1:ro-1 
    allAxes=Bt(ii:ro,1:3); 
    repeachAxis = allAxes(ones(ro-ii+1,1),1:3); 
    c = [repeachAxis(:,2).*allAxes(:,3)-repeachAxis(:,3).*allAxes(:,2) 
     repeachAxis(:,3).*allAxes(:,1)-repeachAxis(:,1).*allAxes(:,3) 
     repeachAxis(:,1).*allAxes(:,2)-repeachAxis(:,2).*allAxes(:,1)]; 
    crossedAxis = reshape(c,size(repeachAxis)); 
    normedAxis = sqrt(sum(crossedAxis.^2,2)); 
    dottedAxis = sum(repeachAxis.*allAxes,2); 
    angbtwn(1:ro-ii+1,ii) = atan2(normedAxis,dottedAxis)*180/pi; 
end 
angbtwn(1,:)=[]; %angle btwn vec and itself 
%only upper left triangle are values...

仍然很長,甚至預先分配...所以我嘗試做稀疏,但沒有實施正確的:

[ro,col]=size(Bt); 
%spalloc: 
angbtwn = sparse([],[],[],ro,ro,ro*(ro-1)/2);%zeros(ro-1); %cell(ro,1) 
for ii=1:ro-1 
    ...same 
    angbtwn(1:ro-ii+1,ii) = atan2(normedAxis,dottedAxis)*180/pi; %WARNED: indexing = >overhead 
    % WHAT? Can't index sparse?? what's the point of spalloc then? 
end

所以如果我的邏輯可以改進,或者稀疏是真的要走的路,我只是不能實現它,讓我知道在哪裏改進。謝謝你的幫助。

回答

0

您是否試圖得到之間的角度Bt?如果Bt有200萬向量,每個向量都有一萬億對(顯然)需要內部產品來獲得角度。我不知道任何一種優化都會幫助這個操作在單個機器上的MATLAB中在合理的時間內完成。

在任何情況下,可以把這個問題成矩陣乘法單位矢量的矩陣之間:

N=1000; 
Bt=rand(N,4); % for testing. A matrix of N (row) vectors of length 4. 
[ro,col]=size(Bt); 

magnitude = zeros(N,1); % the magnitude of each row vector. 
units = zeros(size(Bt)); % the unit vectors 

% Compute the unit vectors for the row vectors 
for ii=1:ro 
    magnitude(ii) = norm(Bt(ii,:)); 
    units(ii,:) = Bt(ii,:)/magnitude(ii); 
end 

angbtwn = acos(units * units') * 360/(2*pi); 

但你會矩陣乘法爲稍大N.期間耗盡存儲器

+0

嗯,我會說實話,我從來沒有想到會多大,我想我需要思考的新方法。 ..但是,無論如何,這是一個很好的學習經驗。另外 - 矢量Bt(:,1:3)都是單位矢量 - 並不認爲這很重要。謝謝。 – Jon

0

您可能需要使用pdist'cosine'距離來計算1-cos(angbtwn)
另一個振作了這種方法,它不計算n^2值,但exaxtly .5*(n-1)*n唯一值:)