2016-10-24 1 views
2

Ich habe Julia gelernt, indem ich versucht habe, eine einfache Starrkörpersimulation zu schreiben, aber ich bin immer noch etwas verwirrt über die Zuweisung und Mutation von Variablen.Wie setze ich die Elemente eines Vektors so, dass sie auf das erste Element in einem Array von Arrays zeigen?

Ich speichere die Punkte, die die Form eines Körpers bilden, in ein Array von Arrays, wobei ein Vektor die x, y, z Koordinaten eines Punktes enthält. Zum Zeichnen des Körpers mit PyPlot werden die Punkte zuerst von lokalen Koordinaten in Weltkoordinaten transformiert und dann drei Feldern zugewiesen, die die x-, y- und z-Koordinaten für die Punkte enthalten. Ich möchte, dass die drei Arrays nur auf das Array von Array-Werten verweisen, anstatt Kopien der Werte zu haben.

Der relevante Teil meines Codes sieht wie folgt aus

type Rigidbody 
    n::Integer 
    k::Integer 
    bodyXYZ::Array{Array{Float64,1},2} 
    worldXYZ::Array{Array{Float64,1},2} 
    worldX::Array{Float64,2} 
    worldY::Array{Float64,2} 
    worldZ::Array{Float64,2} 
    Rotmat::Array{Float64,2} 
    x::Array{Float64,1} 
end 
# body.worldXYZ[1,1] = [x; y; z] 
# and body.worldX[1,1] should be body.worldXYZ[1,1][1] 

function body_to_world(body::Rigidbody) 
    for j in range(1, body.k) 
     for i in range(1, body.n) 
      body.worldXYZ[i,j] = body.x + body.Rotmat*body.bodyXYZ[i,j] 
      body.worldX[i,j] = body.worldXYZ[i,j][1] 
      body.worldY[i,j] = body.worldXYZ[i,j][2] 
      body.worldZ[i,j] = body.worldXYZ[i,j][3] 
     end 
    end 
    return nothing 
end 

Nach dem body_to_world() aufrufen und die Überprüfung der Elemente mit === sie wahr beurteilen, aber wenn ich dann zum Beispiel gesetzt

body.worldXYZ[1,1][1] = 99.999 

Die Änderung wird nicht in body.worldX widergespiegelt. Das Problem ist wahrscheinlich etwas trivial, aber wie ich aus meinem Code ersehen kann, bin ich ein Anfänger und könnte etwas Hilfe gebrauchen.

Antwort

3
body.worldX[i,j] = body.worldXYZ[i,j][1] 

Hier stellen Sie eine Nummer auf eine Zahl ein. Nummern sind nicht änderbar, daher wird body.worldX[i,j] nicht auf body.worldXYZ[i,j][1] verweisen. Was Sie denken ist, dass der Wert eines Arrays eine Referenz sein wird, aber Zahlen haben keine Referenzen, nur der Wert selbst.


Ich würde jedoch wagen zu sagen, dass wenn Sie so etwas tun, gehen Sie über das Problem falsch. Sie sollten wahrscheinlich irgendwo Typen verwenden. Denken Sie daran, Typen in Julia geben gute Leistung, also haben Sie keine Angst vor ihnen (und unveränderliche Typen sollten fast perfekt nach Karneval PR optimiert werden, so dass es wirklich keine Notwendigkeit gibt, Angst zu haben). Stattdessen würde ich world::Array{Point,2} machen, wo

immutable Point{T} 
    x::T 
    y::T 
    z::T 
end 

Dann können Sie body.world[i,j].x erhalten für die x koordinieren, etc. Und dann kostenlos können Sie map((i,j)->Ref(body.world[i,j].x),size(body.world)...) verwenden, um ein Array von Verweisen auf die x ‚s zu erhalten.

Oder Sie sollten Ihrem Typ Absendungen hinzufügen. Zum Beispiel

import Base: size 
size(RigidBody) = (n,k) 

jetzt size(body) Ausgänge (n,k), als ob es ein Array ist. Sie können die Array-Schnittstelle mit getindex und setindex! vervollständigen. Diese Art des Hinzufügens von Versendungen zu Ihrem Typ hilft dabei, den Code immens aufzuräumen.

+0

Vielen Dank für die Hilfe! Das Verwenden von Typen für die Punkte war etwas, das ich in Betracht gezogen habe, aber bis jetzt bin ich nicht dazu gekommen. Können Sie die Wahl von unveränderlichen obwohl näher ausführen? – Boxed

+0

Okay, ich habe versucht, ein Array von Refs zu erstellen, aber es wird immer noch nicht aktualisiert – Boxed

+0

Unveränderlich bedeutet, dass Sie die Werte nicht ändern können. Anstatt also das "x" eines Punktes zu ändern, müssen Sie einen neuen "Punkt" erstellen. Allerdings erlaubt diese Wahl dem Compiler, "jeden Overhead" (es gibt ein winziges Bit, aber eine v0.6-Änderung, das das korrigiert) im Wesentlichen zu optimieren, was bedeutet, dass bei Verwendung von immutablen Elementen alles zu syntaktischem Zucker wird, ohne Code lesbarer zu machen Leistung opfern. Veränderbare Typen können sich ändern (Arrays sind veränderbar), daher können sie nicht so gut optimiert werden. –

Verwandte Themen