如何使用矢量化代码从MATLAB中的两个矢量生成所有对?

如何使用矢量化代码从MATLAB中的两个矢量生成所有对?,matlab,combinations,Matlab,Combinations,现在我不止一次需要在MATLAB中生成两个向量的所有可能对,我用它来处理循环,循环占用了相当多的代码行 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

现在我不止一次需要在MATLAB中生成两个向量的所有可能对,我用它来处理循环,循环占用了相当多的代码行

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的风格


n、 b.
nchoosek
不做我需要的反向对(即
21
以及
12
),我不能只是反向并附加
nchoosek
输出,因为对称对将包含两次

您可以使用
repmat
复制矩阵,然后使用
restrape
将结果转换为列向量

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
当然,您可以去掉上面示例中的所有中间变量。

试试看

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

看。虽然这并不是该函数的确切用途,但如果你看它很有趣,你所要求的正是它的功能。

另一种收集解决方案:

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

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

你要找的是

是实现它的函数。您可以在线性代数软件包中找到它,因此您需要执行以下操作:

   >> 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    

这里有一个更像MATLAB的方法来找到这些组合。这一个也可以很容易地扩展到2个以上的向量(以及非数字组合):


您可以使用普通的旧矩阵运算,例如

x = [3,2,1];
y = [11,22,33,44,55];
v = [(ones(length(y),1) * x)(:), (ones(length(x), 1) * y)'(:)]
编辑:这是倍频程语法,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

从R2015a版本开始,您可以使用和:


这种类型的解决方案避免了一些其他解决方案(例如基于的解决方案)所需的额外中间变量,这些解决方案可能会导致较大向量的内存问题。

这是一个很好的重复。我既知道
meshgrid
又知道二维向量的序列化,但从未考虑过用这种方式使用它们。+1:我删除了我的解决方案,我更喜欢你的。不过,我已经冒昧地对其进行了更正,以获得
vec1
vec2
的组合@EitanT:无需重塑。来自
find
的索引始终应该是列向量,以及
vec1(idx1)
等。我认为重塑是必要的。假设
idx1
是一个向量(不管是行还是列),如果
vec1
是一个行向量,那么
vec1(idx1)
也将是一个行向量。这同样适用于
vec2
。请注意,这需要神经网络工具箱。对于那些拥有它的人来说,它似乎是最好的解决方案。就像这样,它比公认的解决方案更好,因为它可以推广到多个向量。@我知道这是一个很晚的答复,但值得未来的访问者知道,与大向量的公认解决方案相比,这是非常缓慢的。值得一提的是,声明做同样事情的函数也可以在上找到。这不是有效的MATLAB语法。
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
>> 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