2015-09-08 8 views
5

I haben eine dreidimensionale Anordnung wie folgt definiert:Passing zweidimensionales Array auf eine Funktion, in Julia

x=zeros(Float64,2,2,2) 

I diejenigen x zugewiesen werden soll durch x auf eine Funktion, eine Schicht zu einem Zeitpunkt übergeben. Die Funktion ist:

function init(p,y) 
    y=ones(p,p) 
end 

und ich werde x passieren, wie folgt:

for k=1:2 
    init(2,x[2,2,k]) 
end 

aber wenn ich das tun, x ist Nullen, nicht diejenigen. Warum?

julia> x 
2x2x2 Array{Float64,3}: 
[:, :, 1] = 
0.0 0.0 
0.0 0.0 

[:, :, 2] = 
0.0 0.0 
0.0 0.0 

Jede Idee, wie Julia zu bekommen diejenigen x zuweisen?

Antwort

3

Ich bin mir nicht sicher, ob ich das verstehe, aber wenn Sie versuchen, x an Ort und Stelle zu ändern, sollten Sie die Dinge ein wenig anders machen.

Der folgende Code sollte tun, was Sie brauchen.

x = zeros(Float64, 2, 2, 2) 

function init!(p, y, k) 
    y[:, :, k] = ones(Float64, p, p) 
end 


for k = 1:2 
    init!(2, x, k) 
end 

Und Sie mögen vielleicht auch im Auge behalten, dass die Standard-Konvention in Julia ist ein Ausrufezeichen im Namen einer Funktion enthält, die ihre Argumente modifizieren. Und wenn ich Ihre Frage verstanden habe, dann wollen Sie Ihre init!() Funktion genau das tun.

+0

Ich denke, die Frage ist, nur eine Schicht auf einmal passieren, nicht die gesamte 3D-Matrix. Wenn Sie genau das tun, übergeben Sie eine Ebene, dann wird scheinbar eine tiefe Kopie dieser Ebene übergeben, und das wird in der 'init'-Funktion geändert, was das Problem ist. – Ferenc

5

Ich bin mir auch nicht sicher, ob ich die Frage verstehe, aber slice(x, :, :, k) wird eine 2d Scheibe von x nehmen.

Wenn Sie x als ein Array von Float64 initialisieren und dann hoffen, eine Matrix zu jedem Element zuzuweisen (was ist, was es scheint, Sie versuchen zu tun), wird das nicht funktionieren --- der Typ von x wird es nicht zulassen. Sie könnten x ein Array von Any machen, und dann wäre das erlaubt.

6

Eine mögliche Lösung ist slice zu verwenden, welches einen SubArray macht:

x = zeros(2, 2, 2) # Float64 by default 

function init!(y) 
    y[:] = ones(y) # change contents not binding 
end 

for k in 1:2 
    init!(slice(x, :, :, k)) # use slice to get SubArray 
end 

Beachten Sie, dass ones(y) zu bekommen einen Vektor von Einsen von der gleichen Größe wie y verwenden können.

Eine SubArray gibt eine Ansicht eines Arrays statt einer Kopie. In zukünftigen Versionen von Julia kann das Indizieren eines Arrays dies standardmäßig angeben, aber derzeit müssen Sie dies explizit tun.

Für eine Diskussion über Werte vs. Bindungen finden

http://www.johnmyleswhite.com/notebook/2014/09/06/values-vs-bindings-the-map-is-not-the-territory/

EDIT: I @ tholy Antwort nicht gesehen hatte, die die gleiche Idee enthält.