Matlab中行索引的笛卡尔积

时间:2016-07-28 11:37:15

标签: matlab cartesian-product

我在Matlab中有一个维度为Amxn的二进制矩阵m>n。我想构建一个维度B的矩阵cxn,列出A中包含的行索引的笛卡尔积的每个元素的行。更清楚地考虑以下示例。

示例:

  %m=4;
  %n=3;

  A=[1 0 1;
     0 0 1;
     1 1 0;
     0 0 1];

  %column 1: "1" are at rows {1,3}
  %column 2: "1" are at row {3}
  %column 3: "1" are at rows {1,2,4}

  %Hence, the Cartesian product {1,3}x{3}x{1,2,4} is 
  %{(1,3,1),(1,3,2),(1,3,4),(3,3,1),(3,3,2),(3,3,4)} 

  %I construct B by disposing row-wise each 3-tuple in the Cartesian product

  %c=6

 B=[1 3 1;
    1 3 2;
    1 3 4;
    3 3 1;
    3 3 2;
    3 3 4];

4 个答案:

答案 0 :(得分:4)

您可以使用debug命令获取笛卡尔积,例如:

combvec

您可以使用产品的关联属性将其扩展为未知数量的列。

A=[1 0 1;...
   0 0 1;...
   1 1 0;...
   0 0 1];

[x y]=find(A);

B=combvec(x(y==1).',x(y==2).',x(y==3).').';

% B =
%    1   3   1
%    3   3   1
%    1   3   2
%    3   3   2
%    1   3   4
%    3   3   4

答案 1 :(得分:3)

一种解决方案(不带工具箱):

removeEventListener

答案 2 :(得分:3)

您可以使用use accumarray来获取每列的非零元素行索引的向量。这适用于任意数量的列

[ii, jj] = find(A);
vectors = accumarray(jj, ii, [], @(x){sort(x.')});

然后应用this answer来有效地计算这些向量的笛卡尔乘积:

n = numel(vectors);
B = cell(1,n);
[B{end:-1:1}] = ndgrid(vectors{end:-1:1});
B = cat(n+1, B{:});
B = reshape(B,[],n);

在你的例子中,这给出了

B =
     1     3     1
     1     3     2
     1     3     4
     3     3     1
     3     3     2
     3     3     4

答案 3 :(得分:2)

简而言之,我会使用find生成笛卡尔积所需的索引,然后使用ndgrid来执行这些索引的笛卡尔乘积。这样做的代码是:

clear
close all
clc

A = [1 0 1;
     0 0 1;
     1 1 0;
     0 0 1];

[row,col] = find(A);
[~,ia,~] = unique(col);
n_cols = size(A,2);
indices = cell(n_cols,1);

for ii = 1:n_cols-1
  indices{ii} = row(ia(ii):ia(ii+1)-1);
end
indices{end} = row(ia(end):end);

cp_temp = cell(n_cols,1);
[cp_temp{:}] = ndgrid(indices{:});

cp = NaN(numel(cp_temp{1}),n_cols);
for ii = 1:n_cols
  cp(:,ii) = cp_temp{ii}(:);
end
cp = sortrows(cp);
cp