0

ベクトルの「N 次元積」を取得するコードを作成しようとしています。たとえば、長さ L、x & y の 2 つのベクトルがある場合、「2 次元積」は単純に通常のベクトル積 R=x*y であり、R、R(i、 j) は、x の i 番目の要素と y の j 番目の要素の積、別名 R(i,j)=x(i)*y(j) です。

問題は、任意の次元に対して matlab でこれをエレガントに一般化する方法です。これは、3 つのベクトル x、y、z があり、R(i,j,k)=x(i)*y(j)*z(k) となる 3 次元配列 R が必要です。

4 つのベクトル x1、x2、x3、x4 についても同じです: R(i1,i2,i3,i4)=x1(i1)*x2(i2)*x3(i3)*x4(i4) など...

また、事前に次元数がわかりません。コードは任意の数の入力ベクトルを処理できる必要があり、入力ベクトルの数は最終的な答えの次元に対応します。

これを行うための簡単なmatlabのトリックはありますか?具体的にはRの各要素を通過しないようにしますか?

ありがとう!

4

2 に答える 2

3

「通常のベクトル積」とは、外積を意味すると思います。

いずれにせよ、ndgrid機能を使用できます。bsxfunもう少し簡単なので、使用するよりもこれが好きです。

% make some vectors
w = 1:10;
x = w+1;
y = x+1;
z = y+1;

vecs = {w,x,y,z};

nvecs = length(vecs);

[grids{1:nvecs}] = ndgrid(vecs{:});

R = grids{1};
for i=2:nvecs
    R = R .* grids{i};
end;

% Check results
for i=1:10
    for j=1:10
        for k=1:10
            for l=1:10
                V(i,j,k,l) = R(i,j,k,l) == w(i)*x(j)*y(k)*z(l);
            end;
        end;
    end;
end;

all(V(:))

    ans = 1
于 2013-07-19T19:01:31.567 に答える
1

組み込み関数bsxfunは、役立つはずの高速ユーティリティです。次元が一致しない 2 つの入力に対して、要素ごとに 2 つの入力関数を実行するように設計されています。シングルトンの次元が拡張され、非シングルトンの次元が一致する必要があります。(紛らわしいように聞こえますが、一度理解すると、多くの点で役立ちます。)

あなたの問題を理解しているので、各ベクトルの次元形状を調整して、定義する必要がある次元を定義できます。次に、ネストされたbsxfun呼び出しを使用して乗算を実行します。

コード例は次のとおりです。

%Some inputs, N-by-1 vectors
x = [1; 3; 9];
y = [1; 2; 4];
z = [1; 5];

%The computation you describe, using nested BSXFUN calls
bsxfun(@times, bsxfun(@times, ...  %Nested BSX fun calls, 1 per dimension
    x, ...                         %    First argument, in dimension 1
    permute(y,2:-1:1) ) , ...      %    Second argument, permuited to dimension 2
    permute(z,3:-1:1) )            %    Third argument, permuted to dimension 3

%Result
% ans(:,:,1) =
%      1     2     4
%      3     6    12
%      9    18    36
% ans(:,:,2) =
%      5    10    20
%     15    30    60
%     45    90   180

任意の数の次元を処理するには、再帰またはループ構成を使用してこれを拡張できます。ループは次のようになります。

allInputs = {[1; 3; 9], [1; 2; 4], [1; 5]};

accumulatedResult = allInputs {1};
for ix = 2:length(allInputs)
    accumulatedResult = bsxfun(@times, ...
        accumulatedResult, ...
        permute(allInputs{ix},ix:-1:1));
end
于 2013-07-19T18:50:08.313 に答える