我有一个三维数组定义为:
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将其分配给x
吗?
答案 0 :(得分:5)
我也不确定我是否理解这个问题,但是slice(x, :, :, k)
会花费2d x
。
如果您正在将x
初始化为Float64
数组,然后希望为每个元素分配一个矩阵(这就是您尝试做的事情),那个不会工作的人...... x
的类型不会允许它。您可以将x
设为Any
数组,然后允许这样做。
答案 1 :(得分: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!()
函数能够做到这一点。
答案 2 :(得分: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)
会给你一个错误 Invalid use of @view macro: argument must be a reference expression
。为了解决这个问题,可以使用 kludge @views
将所有 SubArray 转换为视图,或者您可以将参数括在括号中。
otherfunc!(@views x[:,:,1], 10)
otherfunc!(@view( x[:,:,1]), 10)
您可以在本演示文稿中找到有关数组和矩阵操作的更多信息: (Youtube) Arrays: slices and views