2016-04-03 15 views
6

Ich habe ein 2D-Array, das ich ändern möchte, um ein bestimmtes Element in einer Zeile mit allen Elementen vor ihm zu summieren, also zum Beispiel, wenn ich ein Array habe:Effizienter Weg, um ein Array von Ganzzahlen in Julia zu summieren

[1 2; 3 6; 4 7; 4 8] 

ich möchte es zu transformieren können

[1 2; 4 8; 8 15; 12 23] 

ich tun kann, so das folgende snippet in julia mit:

for i in 1:10, 
    for k in 2:size(d,1), 
      d([k,i] += d[k-1,i)]; 
    end 
end 

Aber ich nehme an, dass es einen effizienteren Weg geben muss, dies zu tun?

+3

Wenn Sie mit "effizient" Sie "Leistung" meinen, solange Sie diese Schleife in eine Funktion einfügen, wird es im Grunde genauso effizient wie die Bibliotheksfunktion --- die Bibliotheksfunktion unterscheidet sich nur in der Allgemeinheit, so dass Sie Wählen Sie eine beliebige Dimension. Eine der Freuden der Verwendung von Julia ist, dass Sie nicht für alles auf Bibliotheksfunktionen angewiesen sind. – tholy

Antwort

16

Ja, es gibt: cumsum

julia> d = [1 2; 3 6; 4 7; 4 8] 
4x2 Array{Int64,2}: 
1 2 
3 6 
4 7 
4 8 

julia> cumsum(d) 
4x2 Array{Int64,2}: 
    1 2 
    4 8 
    8 15 
12 23 
4

Per @ tholy Kommentar, die ehrfürchtige Sache über julia ist, dass integrierte Funktionen nicht speziell sind und sind nicht auf magische Weise schneller als benutzerdefinierte Einsen. Sie sind beide schnell. Ich änderte Ihre Funktion und ich habe es etwa das gleiche wie die eingebauten in cumsum auszuführen:

function testA!(arr) 
    @inbounds for i in 1:size(arr, 2) 
     tmp = arr[1, i] 
     for k in 2:size(arr,1) 
      tmp += arr[k, i] 
      arr[k,i] = tmp 
     end 
    end 
    arr 
end 

function testB!(arr) 
    cumsum!(arr, arr) 
end 

Ich konstruierte Testanordnungen:

arr = rand(1:100, 10^5, 10^2) 
arr2 = copy(arr) 

und ich habe folgende Timings:

@time testA!(arr) 
0.007645 seconds (4 allocations: 160 bytes) 

@time testB!(arr2) 
0.007704 seconds (4 allocations: 160 bytes) 

die im Grunde äquivalent sind.

Verwandte Themen