Так что у меня этот кусок кода (в MATLAB)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
может быть n
, а число g
может быть m
. Код должен по-прежнему возвращать все уникальные возможные комбинации g
. У меня такое чувство, что рекурсия должна быть использована, но все мои попытки потерпели неудачу.
Также allvecfields(k,:)
просто означает k-я строка, все столбцы. Даже если ваш ответ содержит C/C++ или Java-код (без каких-либо специальных функций от них), это подходит для меня. Я переведу его в MATLAB.
Я просмотрел combvec
и файл allcomb
, но они не делают то, что мне нужно. Например, 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');
Дает то, что я хочу, но это не помогает в обобщении.
EDIT: Исправлена ошибка в последней строке первого кодового блока. Требуемая мощность для этого случая достаточно велика (27 столбцов), но если мы только что g1
и g2
, то выход будет:
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
EDIT: на основе предложения в комментариях, я был в состоянии переписать приведенный выше код, как,
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'))
Я думаю, что это немного более элегантно, но я до сих пор застрял, как динамически генерировать uMat
учитывая количество столбцов в gMat
. Я не могу поверить, что для этого не существует функции. Любая помощь будет оценена по достоинству.
Желаемый результат, полученный вашим входом, поможет. – thewaywewalk
Я думаю, что если вы складываете все 'g' в матрицу, а также создаете вектор с продуктами' u' и 'symm', это может привести вас в правильном направлении и сделать код эффективным. –
Обратите внимание, что транспонирование - это просто '.'' – percusse