如何将向量的元素设置为指向数组数组中的第一个元素?

How do I set a vector's elements to point to the first element in an array of arrays?

我一直在通过尝试编写一个简单的刚性 body 模拟来学习 Julia,但我对变量的赋值和变异仍然有些困惑。

我将构成 body 形状的点存储到一个数组数组中,其中一个向量包含一个点的 x、y、z 坐标。为了使用 PyPlot 绘制 body,首先将点从本地坐标转换为世界坐标,然后分配给三个数组,分别保存这些点的 x、y 和 z 坐标。我想让这三个数组只引用数组值的数组而不是值的副本。

我的代码的相关部分如下所示

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

在调用 body_to_world() 并使用 === 检查元素后,它们的计算结果为 true 但是如果我然后例如设置

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

更改未反映在 body.worldX 中。问题可能是微不足道的,但从我的代码可以看出,我是初学者,需要一些帮助。

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

您在此处将一个数字设置为一个数字。数字是不可变的,所以 body.worldX[i,j] 不会引用回 body.worldXYZ[i,j][1]。你在想的是数组的值将是一个引用,但数字没有引用,只有值本身。


但是,我敢说,如果您这样做,那您就错了。您可能应该在某处使用类型。请记住,Julia 中的类型具有良好的性能,所以不要害怕它们(不可变类型在 carneval 的 PR 之后应该几乎完美优化,所以真的没有必要害怕)。相反,我会让 world::Array{Point,2} where

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

然后你可以获得 body.world[i,j].x 作为 x 坐标等。然后你可以免费使用 map((i,j)->Ref(body.world[i,j].x),size(body.world)...) 来获取对 x 的引用数组的。

或者,您应该为您的类型添加调度。例如

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

现在 size(body) 输出 (n,k),就像它是一个数组一样。用getindexsetindex!即可完成数组接口。这种向您的类型添加分派将极大地帮助清理代码。