Domanda Come generare tutte le coppie da due vettori in MATLAB usando un codice vettoriale?


Più di una volta ho avuto bisogno di generare tutte le coppie possibili di due vettori in MATLAB, cosa che faccio con i loop che occupano una discreta coda di codice, ad esempio.

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

Genera ...

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

Ci deve essere un modo migliore per fare ciò che è più sofisticato di MATLAB?

N.B. nchoosek non fa le coppie invertite che è ciò di cui ho bisogno (ad es. 2 1 così come 1 2), Non posso semplicemente invertire e aggiungere il nchoosek output perché le coppie simmetriche saranno incluse due volte.


44
2017-09-16 15:26


origine


risposte:


Provare

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

Vedere il Documentazione MESHGRID. Anche se questo non è esattamente ciò che questa funzione è, ma se si strizza l'occhio a ciò che è divertente, quello che stai chiedendo è esattamente quello che fa.


87
2017-09-16 15:37



Puoi usare

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

11
2018-05-12 14:35



Un'altra soluzione per la raccolta:

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

3
2018-04-09 16:42



Potresti farlo replicando le matrici usando repmat e poi trasformando il risultato in un vettore colonna usando 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

Naturalmente, puoi eliminare tutte le variabili intermedie dell'esempio sopra.


3
2017-09-16 15:37



Ecco un altro modo MATLAB per trovare le combinazioni. Questo può anche essere facilmente esteso a più di 2 vettori (e anche combinazioni non numeriche):

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
2018-05-24 13:14



Puoi usare semplici operazioni a matrice vecchia, ad es. in

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

Modificare: questa è la sintassi di Octave, MATLAB sarà simile a questo:

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(:)]

in entrambi i casi, il risultato sarà

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

1
2018-05-23 20:59



Quello che stai cercando è il prodotto cartesiano

cartprod è la funzione che lo implementa. Puoi trovarlo nel pacchetto di algebra lineare, quindi dovresti fare:

   >> 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
2018-04-11 19:32