web-dev-qa-db-ja.com

ベクトル化されたコードを使用してMATLABで2つのベクトルからすべてのペアを生成する方法は?

MATLABで2つのベクトルのすべての可能なペアを生成する必要がありました。これは、かなりの数行のコードを使用するforループで行います。

vec1 = 1:4;
vec2 = 1:3;
i = 0;
pairs = zeros([4*3 2]);
for val1 = vec1
    for val2 = vec2
         i = i + 1;
         pairs(i,1) = val1;
         pairs(i,2) = val2;
    end
end

生成...

1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1 
4 2
4 3

これを行うためのより良い方法がなければなりませんが、これはよりMATLAB's風ですか?

n.b. nchoosekは、私が必要とする逆のペアを実行しません(つまり、2 1 と同様 1 2)、対称ペアが2回含まれるため、nchoosek出力を逆に追加することはできません。

46
Brendan

試して

[p,q] = meshgrid(vec1, vec2);
pairs = [p(:) q(:)];

MESHGRIDドキュメント を参照してください。これはその機能の目的ではありませんが、面白いことに目を細めると、求めているのはまさにその機能です。

91
Lambdageek

使用してもよい

a = 1:4;
b = 1:3;
result = combvec(a,b);
result = result'
12
efirvida

repmatを使用して行列を複製し、reshapeを使用して結果を列ベクトルに変換することにより、それを行うことができます。

a = 1:4;
b = 1:3;
c = reshape( repmat(a, numel(b), 1), numel(a) * numel(b), 1 );
d = repmat(b(:), length(a), 1);
e = [c d]

e =

     1     1
     1     2
     1     3
     2     1
     2     2
     2     3
     3     1
     3     2
     3     3
     4     1
     4     2
     4     3

もちろん、上記の例からすべての中間変数を取り除くことができます。

3
Praetorian

収集のための別のソリューション:

[idx2, idx1] = find(true(numel(vec2),numel(vec1)));
pairs = [reshape(vec1(idx1), [], 1), reshape(vec2(idx2), [], 1)];
3
yuk

単純な古い行列演算を使用できます。に

x = [3,2,1];
y = [11,22,33,44,55];
v = [(ones(length(y),1) * x)(:), (ones(length(x), 1) * y)'(:)]

編集:これはOctave構文です。MATLABは次のようになります。

x = [3,2,1];
y = [11,22,33,44,55];
A = ones(length(y),1) * x;
B = (ones(length(x), 1) * y)';
v = [A(:) B(:)]

どちらの場合でも、結果は

v =
 3    11
 3    22
 3    33
 3    44
 3    55
 2    11
 2    22
 2    33
 2    44
 2    55
 1    11
 1    22
 1    33
 1    44
 1    55
2
jihor

ここでは、組み合わせを見つけるためのよりMATLABのような方法です。これは、2つ以上のベクトル(および非数値の組み合わせ)に簡単に拡張することもできます。

v1 =   1:  1:  3;
v2 =  11: 11: 44;
v3 = 111:111:555;

dimensions = cellfun(@numel, {v1,v2,v3});

[i1,i2,i3] = ind2sub(dimensions, 1:prod(dimensions));

combinations = [v1(i1); v2(i2); v3(i3)]'
1
pAtrick

バージョンR2015aから、これを行うには repelem および repmat を使用します。

>> vec1 = 1:4;
>> vec2 = 1:3;
>> pairs = [repelem(vec1(:), numel(vec2)) ...
            repmat(vec2(:), numel(vec1), 1)]

pairs =

     1     1
     1     2
     1     3
     2     1
     2     2
     2     3
     3     1
     3     2
     3     3
     4     1
     4     2
     4     3

このタイプのソリューションは、他のいくつかのソリューション( meshgrid に基づくものなど)で必要とされる追加の中間変数を回避します。

1
gnovice

探しているのは デカルト積 です

cartprod は、それを実装する関数です。線形代数パッケージで見つけることができるので、次を行う必要があります。

   >> pkg install -forge linear-algebra
   >> pkg load linear-algebra 
   >> sortrows(cartprod(1:4,1:3))                                            
    ans =                                                                                           
       1   1                                                                  
       1   2                                                                  
       1   3                                                                  
       2   1                                                                  
       2   2                                                                  
       2   3                                                                  
       3   1                                                                  
       3   2                                                                  
       3   3                                                                  
       4   1                                                                  
       4   2                                                                  
       4   3    
0
elviejo79