MATLAB中的笛卡尔积

21

以下是我遇到问题的简化版本。假设我有一个向量:

p=[1 5 10] 

还有另一个

q=[.75 .85 .95]

我想要得到以下矩阵:

res=[1, .75;     1, .85;     1, .95;     5, .75;     5, .85;     5, .95;    10, .75;    10, .85;    10, .95]

这也被称为笛卡尔积。 我该怎么做?


实际上,我发现http://www.mathworks.com/matlabcentral/fileexchange/5898 正好做我想要的事情! - emper
6
你应该把那个作为答案并接受自己的答案来关闭问题。 - learnvst
3个回答

48

这是一种方法:

[X,Y] = meshgrid(p,q);
result = [X(:) Y(:)];

输出结果为:

result =

    1.0000    0.7500
    1.0000    0.8500
    1.0000    0.9500
    5.0000    0.7500
    5.0000    0.8500
    5.0000    0.9500
   10.0000    0.7500
   10.0000    0.8500
   10.0000    0.9500

虽然这确实是笛卡尔积,但这不是OP所要求的。它需要一个额外的步骤result=sum(result,2)才能符合要求。 - jpjacobs
4
我不认为那是正确的。如果你仔细看一下原文提出的问题中的结果矩阵,它似乎是2x9而不是1x9。第一行是“1, 0.75”(注意“1 .75”中间的空格),而不是1.75。通过他提供的链接到FileExchange脚本进一步确认了这一点,他说这个脚本完全正确。我同意这很令人困惑——我不得不眯着眼睛才能看清楚发生了什么! - nibot
你说得完全正确。我会修改他的帖子以便更加清晰明了。 - jpjacobs

5

与@nibot所描述的方法类似,可以在Matlab中心文件交换中找到。

它将解决方案推广到任意数量的输入集。以下是简化版本的代码:

function C = cartesian(varargin)
    args = varargin;
    n = nargin;

    [F{1:n}] = ndgrid(args{:});

    for i=n:-1:1
        G(:,i) = F{i}(:);
    end

    C = unique(G , 'rows');
end

例如:
cartesian(['c','d','e'],[1,2],[50,70])

ans =

    99     1    50
    99     1    70
    99     2    50
    99     2    70
   100     1    50
   100     1    70
   100     2    50
   100     2    70
   101     1    50
   101     1    70
   101     2    50
   101     2    70

2

这里有一个名为cartesian_product的函数,它可以处理任何类型的输入,包括字符串数组,并返回一个表格,其中列名与输入变量的名称相匹配。不是变量的输入将被赋予类似于var1var2等名称。

function tbl = cartesian_product(varargin)
    names = arrayfun(@inputname, 1:nargin, 'UniformOutput', false);
    
    for i = 1:nargin
        if isempty(names{i})
            names{i} = ['var' num2str(i)];
        end
    end
    
    rev_args = flip(varargin);
    
    [A{1:nargin}] = ndgrid(rev_args{:});

    B = cellfun(@(x) x(:), A, 'UniformOutput', false);
    C = flip(B);
    
    tbl = table(C{:}, 'VariableNames', names);
end

>> x = ["a" "b"];
>> y = 1:3;
>> z = 4:5;
>> cartesian_product(x, y, z)

ans =

  12×3 table

     x     y    z
    ___    _    _

    "a"    1    4
    "a"    1    5
    "a"    2    4
    "a"    2    5
    "a"    3    4
    "a"    3    5
    "b"    1    4
    "b"    1    5
    "b"    2    4
    "b"    2    5
    "b"    3    4
    "b"    3    5

>> cartesian_product(1:2, 3:4)

ans =

  4×2 table

    var1    var2
    ____    ____

     1       3  
     1       4  
     2       3  
     2       4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接