在 Julia 中将二维数组传递给函数

5

我有一个定义为三维数组:

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

我希望通过将变量x逐层传递给函数,来将值为1的赋值给x。这个函数是:
function init(p,y)
   y=ones(p,p)
end

我将按照以下方式传递x

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

但是当我这样做时,x 是零,而不是一。为什么?
julia> x
2x2x2 Array{Float64,3}:
[:, :, 1] =
 0.0  0.0
 0.0  0.0

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

有没有办法让Julia将“1”分配给x
4个回答

6

一种可能的解决方案是使用 slice,它可以创建一个 SubArray

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

请注意,您可以使用ones(y)来获得与y相同大小的全1向量。 SubArray提供了一个数组的视图,而不是副本。在未来的Julia版本中,对数组进行索引可能会默认给出这个视图,但目前必须明确指定。
关于值和绑定的讨论,请参见: http://www.johnmyleswhite.com/notebook/2014/09/06/values-vs-bindings-the-map-is-not-the-territory/ 编辑:我没有看到@tholy的回答,其中包含相同的想法。

5
我不确定是否理解问题,但是slice(x, :, :, k)将获取x的一个二维切片。
如果您想将x作为Float64数组初始化,然后希望将矩阵分配给每个元素(这似乎是您试图做的),那么这样做不起作用-—x的类型不允许。您可以将x设置为Any数组,然后就允许这样做。

3

我不确定我理解了您的意思,但如果您想要就地修改x,则需要稍微改变一下做法。

下面的代码应该可以满足您的需求。

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

你还需要记住,Julia 的标准约定是在修改其参数的函数名称中包含一个感叹号。如果我理解你的问题正确,那么你想让你的 init!() 函数正好做到这一点。


我认为这个问题只是关于一次只传递一个层面,而不是整个三维矩阵。如果你只是这样做,只传递一个层面,那么显然会传递一个该层面的深拷贝,并且在init函数中被修改,这就是问题所在。 - Ferenc

0
很多东西在Julia中发生了变化,我想更新这个答案以反映Julia 1.5的变化(可能大部分变化都是在1.0中)。虽然我希望现代的x[:, :, k]能够工作,因为它仍然被称为SubArray,但实际上当它在表达式中时,它现在是复制的。相反,您必须使用view()
x= zeros(2, 2, 2)

function init!(y)
    y[:]= ones(size(y))
end

init!(view(x, :, :, 1))   # get reference to original items

这将为您提供所需的结果:
julia> x
2×2×2 Array{Float64,3}:
[:, :, 1] =
 1.0  1.0
 1.0  1.0

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

还有一些辅助宏可以以更易读的形式编写它,

init!(@view x[:,:,1])

但是如果您有其他参数,那么您可能会遇到贪婪的宏解析的危险。

otherfunc!(@view x[:,:,1], 10)

如果你使用了无效的@view宏,会出现错误Invalid use of @view macro: argument must be a reference expression。为了解决这个问题,有一个临时的方法是使用@views将所有的SubArray转换成视图,或者你可以将参数用括号括起来。

otherfunc!(@views x[:,:,1], 10)
otherfunc!(@view( x[:,:,1]), 10)

您可以在此演示文稿中找到有关数组和矩阵操作的更多信息: (Youtube) 数组:切片和视图


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接