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

9o685dep  于 2023-04-06  发布在  Matlab
关注(0)|答案(9)|浏览(164)

现在我不止一次需要在MATLAB中生成所有可能的两个向量对,我用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

会产生...
必须有一个更好的方法来做到这一点,这是更MATLAB的风格?
注意:nchoosek不做我需要的反向对(即2 11 2),我不能只是反向和附加nchoosek输出,因为对称对将被包括两次。

sf6xfgos

sf6xfgos1#

试试看

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

请看MESHGRID documentation。虽然这并不完全是那个函数的用途,但如果你眯着眼睛看它很有趣,你所要求的正是它的作用。

chy5wohz

chy5wohz2#

您可以使用

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

wqsoz72f3#

您可以使用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

当然,你可以从上面的例子中去掉所有的中间变量。

kcrjzv8t

kcrjzv8t4#

另一种收集方法:

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

dgiusagp5#

您正在寻找的是cartesian product
cartprod是实现它的函数。你可以在linear-algebra包中找到它,所以你需要做:

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

iklwldmw6#

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

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

4jb9z9bj7#

从MATLAB R2023a开始,您可以使用combinations函数来完成此操作。

> A = [1,2,3];B=[4,5];
>> C = combinations(A,B)
C =
6×2 table
A    B
_    _
1    4
1    5
2    4
2    5
3    4
3    5

结果是一个表。当所有的数据类型都兼容时(就像这里的情况一样),你可以得到这样的矩阵

>> C.Variables
ans =
1     4
1     5
2     4
2     5
3     4
3     5
daolsyd0

daolsyd08#

这里有一个更像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)]'
hfwmuf9z

hfwmuf9z9#

从版本R2015a开始,您可以使用repelemrepmat执行此操作:

>> 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的解决方案)所需的额外中间变量,这可能会导致较大向量的内存问题。

相关问题