2015-03-30 13 views
6

Ich habe zwei Vektoren x und y, der jeweiligen Längen n und p. Gibt es eine eingebaute Möglichkeit, eine np x 2-Matrix zu schaffen, dieKartesisches Produkt von zwei Vektoren in Julia

x[1] y[1] 
x[1] y[2] 
... 
x[1] y[p] 
x[2] y[1] 
... 
x[n] y[p] 

ich tun kann, wäre, dass eine mit verschachtelter for-Schleife, aber ich bin auf der Suche nach einer integrierten Funktion, wenn es vorhanden ist.

Antwort

6

Julia ist normalerweise sehr schnell in verschachtelten Loops, wenn sie also für Sie richtig funktionieren, sollten Sie die Leistung wahrscheinlich überprüfen, vielleicht einfach dabei bleiben.

Andere Option wäre repmat (dieses ein wenig schneller ist als die Verwendung von Wiederholung) werden:

[repmat(x,1,length(y))'[:] repmat(y,length(x),1)[:]] 

Hat einige schnelle Prüfung beider Methoden:

x=rand(1000) 
y=rand(1000) 

function withrepeat(x,y) 
    [repeat(x, inner=[size(y,1)]) repeat(y, outer=[size(x,1)])] 
end 

function withrepmat(x,y) 
    [repmat(x,1,length(y))'[:] repmat(y,length(x),1)[:]] 
end 

withrepeat(x,y) 
elapsed time: 0.21556302 seconds (95986112 bytes allocated) 

with repmat(x,y) 
elapsed time: 0.075604488 seconds (56000560 bytes allocated) 

nicht sicher, warum so viel Unterschied und ich denke, es gibt noch Raum für Verbesserungen. Die Produktfunktion im Iterators.jl-Paket wurde nicht getestet.

auch ein bisschen mehr Informationen hier: https://groups.google.com/forum/#!topic/julia-users/dtl--SyFgwY

Hoffnung, das hilft.

Versucht ein paar verschachtelte Schleifen und ist in der Tat schneller:

function withloops (x,y) 
    leny=length(y) 
    lenx=length(x) 
    m=leny*lenx 
    OUT = zeros(Float64, m,2) 
    c=1 
    for i = 1:lenx 
     for j = 1:leny 
      OUT[c,1] = x[i] 
      OUT[c,2] = y[j] 
      c+=1 
     end 
    end 
    return OUT 
end 

Und für die gleiche rand(1000) für x und y.

withloops(x,y) 
elapsed time: 0.011350679 seconds (16000128 bytes allocated) 
+1

Hilft' @ inbound' die 'for' Schleife? – rickhg12hs

+1

@ rickhg12hs Es sollte ja, ich war in ein wenig Eile, als ich es gepostet habe, also hatte ich keine Zeit, es richtig zu testen, aber ich werde es morgen tun und den Beitrag entsprechend bearbeiten. Danke für den Vorschlag. – Esteban

+0

Ich habe versucht, @ @ inbounds zu verwenden, aber habe keine merkliche Verbesserung erhalten, vielleicht weil es keine Operationen mit den Arrays gibt und ich nur Werte zuweise? Auch in meinem Computer, der Vektoren mit der Länge 10000 als Eingabe für "x" und "y" verwendet, erzeugte Speicherfehler bei der Verwendung von "repeat" oder "repmat", aber funktionierte gut mit der Nested-Loop-Funktion. – Esteban

4

Hier ist, wie könnte ich es tun:

julia> x = [1, 2, 3, 4]; 

julia> y = [9, 8, 7]; 

julia> [repeat(x, inner=[size(y,1)]) repeat(y, outer=[size(x,1)])] 
12x2 Array{Int64,2}: 
1 9 
1 8 
1 7 
2 9 
2 8 
2 7 
3 9 
3 8 
3 7 
4 9 
4 8 
4 7 

Sie auch einen Blick auf Iterators.j nehmen wollen kann - speziell die product Funktion.

+0

Beachten Sie, dass die Klammern um den 'inner' und' outer' Argumente weglassen kann, so dass die Formel reduziert auf '[Wiederholung (x, innen = Größe (y, 1)) repeat (y, outer = Größe (x, 1))] ' –

3

Dies ist im Iteratoren-Modul enthalten.

Entnommen https://github.com/JuliaLang/Iterators.jl

Iterate über alle Kombinationen im kartesischen Produkt der Eingänge.

Beispiel:

for p in product(1:3,1:2) 
    @show p 
end yields 

p = (1,1) 
p = (2,1) 
p = (3,1) 
p = (1,2) 
p = (2,2) 
p = (3,2) 
Verwandte Themen