在Julia中给多维数组赋值

3
下面这段简单的代码返回了一个我认为意外的结果:
srand(101)

# create a multidimensional array that will house 3 matrices of dimensions 2x2
A = Array(Array{Float64,2},3)

# initialise array with zero matrices (is this the culprit?)
fill!(A, zeros(2,2))

# populate array (some dummy computation to illustrate my problem)
for ii=1:2
   for jj=1:2
      aux = randn(1,3)
      for dd=1:3
         A[dd][ii,jj]=aux[dd]
      end
   end
end

当我运行上述代码时,我的数组A的值为:
3-element Array{Array{Float64,2},1}:
 2x2 Array{Float64,2}:
  1.2821   -2.10146
 -1.00158   1.8163 
 2x2 Array{Float64,2}:
  1.2821   -2.10146
 -1.00158   1.8163 
 2x2 Array{Float64,2}:
  1.2821   -2.10146
 -1.00158   1.8163 

当我随机创建三个2x2矩阵时,为什么它们是相同的?

我知道在Julia中将数组分配给数组时必须小心,但某种程度上我还是犯了错误。

有趣的是,我发现如果我像下面这样初始化A:

for dd=1:3
   A[dd] = zeros(2,2)
end

与其相反,而非使用。
fill!(A, zeros(2,2))

就像上面那样,我得到了我认为正确的结果。
3-element Array{Array{Float64,2},1}:
2x2 Array{Float64,2}:
-0.176283   0.22073 
-1.71021   -0.575144
2x2 Array{Float64,2}:
1.94395   1.09946 
1.65326  -0.446783    
2x2 Array{Float64,2}:
1.2821   -2.10146
-1.00158   1.8163

注意,最后一个矩阵是重复的上面的那个矩阵。 这是数组初始化的问题还是赋值的问题? 我猜这是两者的结合,具体取决于您如何执行它们。 提前致谢。
1个回答

6
你几乎已经自己回答了这个问题。是的,
fill!(A, zeros(2,2))

罪魁祸首是 zeros 命令,每个 A 数组的单元格都包含同一个数组(连接到相同的 2x2 内存点)。函数 zeros 只被调用一次。

通过循环填充数组的单元格。

for dd=1:3
   A[dd] = zeros(2,2)
end

调用函数zeros 3 次,每次返回一个不同的零数组(位于内存中的不同位置)。


相同的数组推导式中的 forA = [zeros(2,2) for i=1:3]。推导式对于这些多维初始化非常方便,特别是因为您可以在同一推导式中迭代多个索引。也许使用 3 维数组而不是 2 维数组的向量更好(如果它们的大小相同)。 - Dan Getz
好的,我看到了与_same array_相关的问题。不想贬低fill!()函数,在这种情况下它并没有什么帮助。建议使用列表推导式可能是一个不错的选择。也许还有其他初始化多维数组的方法吗?谢谢。 - user1438310
如果你使用的是不可变数组,例如FixedSizeArrays,那么填充也就不成问题了。 - tholy

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