MATLAB: 向量求和的所有组合

3

我有一段(MATLAB)代码:

% Define vectorfield
 g1=[5,0,0];
 g2=[0,3,0];
 g3=[0,0,4];

% Define on-off
 u=[0;1];

% Define set to make field symmetric
symm=[1;-1];
k=1;

%% Generate possible combinations of vector fields
for a=1:length(u)
 for b=1:length(symm)
   for c=1:length(u)
     for d=1:length(symm)
       for e=1:length(u)
         for f=1:length(symm)
           allvecfields(k,:)=u(a).*symm(b).*g1+u(c).*symm(d).*g2+u(e).*symm(f).*g3;
           k=k+1;
         end
       end
     end
   end
 end
end

realfields=transpose(unique(allvecfields,'rows'));

每一列的realfields都是g的唯一的正数、负数或零的组合。我需要一些帮助来进行泛化。也就是说,每个g的大小可以是ng的数量可以是m。代码仍然应该返回所有可能的g的唯一组合。我感觉需要使用递归,但我的所有尝试都失败了。
此外,allvecfields(k,:)只是表示第k行,所有列。即使你的答案包含C/C++或Java代码(没有任何特殊的函数),对我来说也没问题。我会将其翻译成MATLAB。
我查看了combvecallcomb文件,但它们不能满足我的需求。例如,transpose(unique(combvec(g1,g2,g3,-g1,-g2,-g3)','rows'))返回一个6x63的矩阵,而不是我想要的3x27。
vals=transpose(unique(combvec(g1,g2,g3)','rows'));
vals=[vals transpose(unique(combvec(-g1,g2,g3)','rows'))];
vals=[vals transpose(unique(combvec(g1,-g2,g3)','rows'))];
vals=[vals transpose(unique(combvec(g1,g2,-g3)','rows'))];
vals=[vals transpose(unique(combvec(g1,-g2,-g3)','rows'))];
vals=[vals transpose(unique(combvec(-g1,g2,-g3)','rows'))];
vals=[vals transpose(unique(combvec(-g1,-g2,g3)','rows'))];
vals=[vals transpose(unique(combvec(-g1,-g2,-g3)','rows'))];
vals=unique(vals','rows');

虽然这可以得到我想要的结果,但不能帮助推广。

编辑:修复了第一个代码块最后一行中的错误。对于此情况所需的输出相当大(27列),但如果我们只有g1g2,则输出将是:

realfields =

-5    -5    -5     0     0     0     5     5     5
-3     0     3    -3     0     3    -3     0     3
 0     0     0     0     0     0     0     0     0

编辑:基于评论中的建议,我已经能够将上述代码重写为:

u=[-1,0,1];
k=1;
for a=1:length(u)
  for b=1:length(u)
    for c=1:length(u)
        uMat(k,:)=[u(a) u(b) u(c)];
        k=k+1;
    end
  end
end

g1=[5,0,0];
g2=[0,3,0];
g3=[0,0,4];
gMat=[g1' g2' g3'];

for a=1:size(uMat,1)
    allvecfields(k,:)=sum(bsxfun(@times,gMat,uMat(a,:)),2);
end

realfields=transpose(unique(allvecfields,'rows'))

我认为这样稍微更加优雅,但我仍然无法解决如何根据gMat中的列数动态生成uMat的问题。我无法相信没有这样的函数存在。任何帮助将不胜感激。


期望的输出将会根据你的输入而产生帮助。 - Robert Seifert
我认为如果您将所有的g堆叠在一个矩阵中,并创建一个包含usymm乘积的向量,这可能会让您朝着正确的方向前进,并使代码更加高效。 - Autonomous
请注意,转置操作仅为 . - percusse
我知道,我将其写成transpose(),这样非MATLAB用户也不会被排除在外。 - ITA
1个回答

0

这是解决方案

g1=[5,0,0];
g2=[0,3,0];
g3=[0,0,4];

gMat=[g1' g2' g3'];

m=size(gMat',1);
allvecfields = zeros(3^m,m);

for k = 1:3^m
 allvecfields(k,:) = double(dec2base(k-1,3,m)-'1');
end

realfields = (allvecfields*gMat')'

感谢Roger Stafford提供这个巧妙的解决方案。


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