2015-03-30 21 views
6

İki vektörü var x ve y, ilgili uzunluklarda n ve p.Julia'da iki vektörün kartezyen ürünü

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

Ben bir döngü için iç içe ama yerleşik bir işlev için arıyorum ile, eğer varsa bunu yapabilir olacak bir np x 2 matris oluşturmak için yerleşik bir yolu var mı. İşte

cevap

6

Julia, iç içe geçmiş döngülerde genellikle çok hızlıdır, bu yüzden onlar sizin için doğru bir şekilde çalışıyorlarsa, muhtemelen performansı kontrol etmelisiniz.

Diğer seçenek (bu bir tekrarını kullanmaktan daha biraz daha hızlı) repmat kullanarak olurdu:

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

mü iki yöntemin bazı hızlı testler:

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) 

Değil emin niçin bu kadar fark ve bence hala iyileşme için bir yer var. Ürün işlevini Iterators.jl paketinde denemedim.

Ayrıca burada biraz daha bilgi: Bu yardımcı olur https://groups.google.com/forum/#!topic/julia-users/dtl--SyFgwY

Umut. x ve y için aynı rand(1000) için,

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 

Ve:

gerçektendir daha hızlı bir iç içe döngüler çift ve çalıştı.

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

' inbounds' 'for' döngüsüne yardım ediyor mu? – rickhg12hs

+1

@ rickhg12hs Evet, gönderdiğimde biraz acelem vardı, bu yüzden düzgün bir şekilde test etmek için zamanım olmadı, ama yarın yapacağım ve yazıyı buna göre düzenleyeceğim. Önerin için teşekkürler. – Esteban

+0

'@ inbounds' kullanmayı denedim ancak farkedilir bir iyileşme elde etmedim, belki de bunun nedeni dizilerle hiçbir işlem yapılmaması ve sadece değerlerin atanmasıdır. Ayrıca, bilgisayarımda, xx ve 'y' için 10000 uzunluktaki vektörleri kullanarak, 'repeat' veya 'repmat' işlevlerini kullanırken bellek hatalarını oluşturdu, ancak yuvalanmış döngüler işleviyle iyi çalıştı. – Esteban

4

bunu yapabilir nasıl:

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 

ayrıca Iterators.j bakmak isteyebilirsiniz - özellikle product fonksiyonunu.

+0

Not)) tekrarla (y, dış = boyut (x, 1))] ' –

3

Bu, Yineleyiciler modülünde sağlanır.

girişlerin kartezyen ürün içindeki bütün birleşimleri üzerinde https://github.com/JuliaLang/Iterators.jl

yineleme 'dan alınmıştır.

Örnek:

Eğer `inner` ve 'outer` argümanlar parantezler ihmal edilebilir, bu nedenle, formül [tekrar (x, iç = boyutu (y, 1' azaltır
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)