2015-03-30 23 views
6

Mam dwa wektory x i y o odpowiednich długościach n i p. Czy jest wbudowany w sposób utworzyć macierz NP x 2, który byłbyKartezjański produkt dwóch wektorów w Julii

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

mogę zrobić z zagnieżdżonej pętli for, ale szukam dla wbudowanej funkcji, jeśli taka istnieje.

Odpowiedz

6

Julia jest zwykle bardzo szybka w zagnieżdżonych pętlach, więc jeśli działają one poprawnie, powinieneś sprawdzić wydajność, może po prostu się z tym uporać.

Inną opcją byłoby korzystania repmat (ten jest trochę szybsze niż przy użyciu powtarzanie):

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

Czy niektóre szybkie testowanie obu metod:

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) 

Nie wiem, dlaczego tak duża różnica i myślę, że wciąż jest miejsce na poprawę. Nie próbowałem funkcji produktu w pakiecie Iterators.jl.

także trochę więcej informacji tutaj: https://groups.google.com/forum/#!topic/julia-users/dtl--SyFgwY

Nadzieja to pomaga.

Próbowaliśmy kilka zagnieżdżonych pętlach i rzeczywiście jest szybsze:

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 

I dla tego samego rand(1000) dla x i y.

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

Czy' @sbounds' pomaga w pętli 'for'? – rickhg12hs

+1

@ rickhg12hs To powinno być tak, byłem trochę pośpiechu, kiedy opublikowałem, więc nie miałem czasu, aby przetestować go poprawnie, ale zrobię to jutro i odpowiednio edytować post. Dzieki za sugestie. – Esteban

+0

Próbowałem używać '@ inbounds', ale nie zauważyłem żadnej poprawy, może dlatego, że nie ma żadnych operacji z tablicami i po prostu przypisuję wartości? Również w moim komputerze używającym wektorów o długości 10000 jako danych wejściowych dla 'x' i' y', powodowało błędy pamięci przy użyciu 'repeat' lub' repmat', ale działało dobrze z funkcją zagnieżdżonych pętli. – Esteban

4

Oto jak mogę to zrobić:

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 

może również chcesz przyjrzeć Iterators.j - konkretnie funkcję product.

+0

Należy zauważyć, że można pominąć wsporniki po 'inner' i' outer' argumentów tak wzór zmniejsza się do '[powtórzenia (x, wewnętrzna = wielkość (y, 1)) repeat (y, outer = size (x, 1))] ' –

3

Jest to dostępne w module Iteratory.

Zrobione z https://github.com/JuliaLang/Iterators.jl

iteracyjne nad wszystkich kombinacjach w iloczyn kartezjański wejść.

przykład:

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) 
Powiązane problemy