基于矩阵A,生成矩阵B,其具有矩阵A的列的所有可能的乘法

时间:2012-10-08 23:12:10

标签: matlab matrix

假设我有一个包含3列的矩阵:c1c2c3,我想创建一个新矩阵,其中每列是其中两列的任何可能产品这个矩阵的列。

所以,如果我有一个 d 列的矩阵,我想用 d + d(d-1)/ 2 + d 列创建一个新矩阵。例如,考虑具有3列c1c2c3的矩阵。我要创建的矩阵应包含c1c2c3c1xc2c2xc3c1xc3,{{列1}},c1^2c2^2

有没有有效的方法呢?

3 个答案:

答案 0 :(得分:4)

我很尴尬发布这个 - 我敢肯定必须有一个更简单的方法(有一个很多更简单的方式 - 请参阅我在答案底部的12月更新),但是这个将完成这项工作:

A = [1 2 3; 4 5 6];
n =  size(A, 2);

B = A(:, reshape(ones(n, 1) * (1:n), 1, n^2)) .* repmat(A, 1, n);
Soln = [A, B(:, logical(reshape(tril(toeplitz(ones(n, 1))), 1, n^2)'))];

计算效率不高,因为在B步骤中我实际上计算了我需要的组合数量的两倍(即我得到c1。* c1,c1。* c2,c1。* c3,c2。 * c1,c2。* c2,c2。* c3,c3。* c1,c3。* c2,c3。* c3),然后在第二步中我只抽出我需要的列(例如我摆脱了c3。* c1因为我已经有了c1。* c3等等。

更新:刚刚开车,我发现了一个更好的方法。您只需构建两个形式为I1 = [1 1 1 2 2 3]I2 = [1 2 3 2 3 3]的索引向量,然后(A(:, I1) .* A(:, I2))将为您提供所有列产品。我现在离开了我的计算机,但稍后会回来并找出构建索引向量的一般方法。我认为使用tril(toeplitz)构造可以很容易地完成它。干杯。将在几个小时内更新。

更新: Rody的第二个解决方案(+1)正是我之前更新过的内容,所以我不打算重复他现在所做的事情。 Yoda的实际上也非常整洁,所以另外+1。

12月更新:有趣的是,在这里工作之后,我不得不为自己的研究重新审视这个问题(编写White的异方差检验)。我现在实际上偏爱一种新的方法,在评论中由@slayton推荐(有点隐秘)。具体来说,使用nchoosek。我的新解决方案如下所示:

T = 20; K = 4;
X = randi(100, T, K);
Index = nchoosek((1:K), 2);
XAll = [X, X(:, Index(:, 1)) .* X(:, Index(:, 2)), X.^2];

nchoosek准确地生成了我们快速轻松地构建交叉产品所需的指数!

答案 1 :(得分:2)

以下内容有点不错:

B = arrayfun(@(x) circshift(A, [0 -x]), 0:size(A,2)-1, 'UniformOutput', false);
B = cat(2, ones(size(A)), B{:});

C = repmat(A, 1, size(A,2)+1) .* B

然而,这将导致矩阵

c1 c2 c3 (c1.*c1) (c2.*c2) (c3.*c3) (c1.*c2) (c2.*c3) (c3.*c1) (c1.*c3) (c2.*c1) (c3.*c2)

其顺序与您提出的顺序不同,且产品不是唯一的。如果您只想要所有独特的产品,请使用:

[sA1, sA2] = size(A);

aa = repmat(1:sA2, sA2,1);

C = [A, A(:,nonzeros(triu(aa))).*A(:,nonzeros(triu(aa.')))]  

导致

c1 c2 c3 (c1.*c1) (c2.*c1) (c2.*c2) (c3.*c1) (c3.*c2) (c3.*c3)

这是一个与您要求不同的序列,但它只包含唯一的产品。

序列对您的目的是否重要?

答案 2 :(得分:1)

这是另一种选择。首先,定义一个函数,该函数返回给定数量列的所有可能的对(根据您在问题中的要求):

cols=@(n)cat(1,num2cell((1:n)'),num2cell((1:n)'*[1,1],2),num2cell(nchoosek(1:n,2),2))

该功能应该是相当不言自明的。尝试查看输出中的一些小值n并亲自查看。有了这个,你可以按照以下步骤进行:

s = RandStream('twister','Seed',1); %for reproducibility 
x = rand(s, 4, 3) %your matrix

%    0.4170    0.1468    0.3968
%    0.7203    0.0923    0.5388
%    0.0001    0.1863    0.4192
%    0.3023    0.3456    0.6852

o = cellfun(@(c)prod(x(:,c),2),cols(size(x,2)),'UniformOutput',0);
out = cat(2,o{:})

%    0.4170    0.1468    0.3968    0.1739    0.0215    0.1574    0.0612    0.1655    0.0582
%    0.7203    0.0923    0.5388    0.5189    0.0085    0.2903    0.0665    0.3881    0.0498
%    0.0001    0.1863    0.4192    0.0000    0.0347    0.1757    0.0000    0.0000    0.0781
%    0.3023    0.3456    0.6852    0.0914    0.1194    0.4695    0.1045    0.2072    0.2368
相关问题