0

大きな配列内のすべてのベクトル間の角度を取得しようとしています ( 1896378x4-EDIT: これは1.7981e+12、角度が必要であることを意味します... 大きすぎますが、コードを最適化する余地がある場合は、とにかくお知らせください)。遅すぎます - まだ完了していません。私が取った最適化へのステップは次のとおりです。

まず、論理的に私が(私が思うに)欲しいもの(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

したがって、私のロジックを改善できる場合、またはスパースが本当に適切な方法であり、それを正しく実装できない場合は、どこを改善すべきか教えてください. ご協力いただきありがとうございます。

4

2 に答える 2

0

を計算するために距離を使用pdistしたい場合があります。 このアプローチのもう1つの特典は、値を計算するのではなく、非常に一意の値を計算することです:)'cosine'1-cos(angbtwn)
n^2.5*(n-1)*n

于 2013-08-06T15:11:23.360 に答える
0

のベクトルのすべてのペア間の角度を取得しようとしていますBtか? 200 万個のベクトルがある場合Bt、それぞれ (明らかに) 1 兆のペアであり、その間の角度を取得するために内積が必要です。単一のマシン上の 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 の行列乗算中にメモリが不足します。

于 2013-08-03T04:18:42.623 に答える