2016-06-14 24 views
2

So habe ich dieses Stück Code (in MATLAB)MATLAB: Alle Kombinationen Summe von Vektoren

% 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')); 

Jede Spalte von realfields ist eine einzigartige positiv, negativ oder Null Kombination des g ‚s. Ich brauche Hilfe, um dies zu verallgemeinern. Das ist die Größe von jedem g kann n sein, und die Nummer von g kann m sein. Der Code sollte immer noch alle eindeutigen möglichen Kombinationen der g zurückgeben. Ich habe das Gefühl, dass Rekursion verwendet werden muss, aber alle meine Versuche sind bisher gescheitert.

Auch allvecfields(k,:) bedeutet nur K-te Zeile, alle Spalten. Auch wenn Ihre Antwort C/C++ oder Java-Code enthält (ohne spezielle Funktionen von ihnen), ist das für mich in Ordnung. Ich werde es in MATLAB übersetzen.

Ich habe combvec und die allcomb Datei angesehen, aber sie tun nicht, was ich brauche. Zum Beispiel gibt transpose(unique(combvec(g1,g2,g3,-g1,-g2,-g3)','rows')) eine 6x63-Matrix zurück, nicht die 3x27, die ich möchte. Doing

Gibt, was ich will, aber das hilft nicht bei der Verallgemeinerung.

EDIT: Fehler in der letzten Zeile des ersten Codeblocks behoben. Die erforderliche Ausgabe für diesen Fall ist recht groß (27 Spalten), aber wenn wir nur g1 und g2 haben dann würde der Ausgang sein:

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: Basierend auf einem Vorschlag in den Kommentaren, ich in der Lage gewesen, neu zu schreiben, den obigen Code wie

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')) 

ich denke, das etwas mehr elegant ist, aber ich immer noch an, wie uMat dynamisch zu generieren, um die Anzahl der Spalten in gMat gegeben steckte. Ich kann nicht glauben, dass dafür keine Funktion existiert. Jede Hilfe wäre willkommen.

+0

Die gewünschte Ausgabe bekam Ihre Eingabe würde helfen. – thewaywewalk

+0

Ich denke, wenn Sie alle 'g' in einer Matrix stapeln und auch einen Vektor mit den Produkten von' u' und 'symm' erstellen, könnte das Sie in die richtige Richtung bringen und den Code effizient machen. –

+0

Beachten Sie, dass transpose ist einfach '.'' – percusse

Antwort

0

Hier ist die Lösung

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')' 

Credits: Roger Stafford für diese geniale Lösung.

Verwandte Themen