【问题标题】:Overlapping Arrays in Julia - solutions with pointers?Julia 中的重叠数组 - 带有指针的解决方案?
【发布时间】:2015-09-14 21:49:43
【问题描述】:

我有一个很大的 Float64 数组 x,并且经常在完全更改该切片之前将其切片视为矩阵。我可以以某种方式将此切片称为y,它已经具有正确的形状。到

x=zeros(10000)
y=x[10:18]
reshape!(y,(3,3))
y=y+eye(3) # this doesn't change x

这不起作用,因为x[10:18] 创建了一个副本。我查看了pointer_to_array,但无法解决。

【问题讨论】:

    标签: pointers julia


    【解决方案1】:

    在 Julia 中生成无拷贝切片的常用工具是SubArrays

    x = zeros(10000)
    y = sub(x, 10:18)
    

    现在更改y 将更改x 的相应元素。 (您也可以使用slice,它与高维数组的行为不同)。

    您也可以使用y = sub(x, A),其中 A 是一个索引数组。不幸的是,reshape(y, 3, 3) 通过将 SubArray 转换为数组来生成值的副本(目前在Julia issue 9874 中讨论,因此将来可能会改变)。使用 y = sub(x, A)A 正确形状的索引矩阵不起作用。

    也许对于您的特定应用程序,这样做就足够了

    x = zeros(10000)
    y = sub(x, 10:18)
    y[:] += vec(eye(3))
    

    根据需要更改x,而不会产生不同形状的切片。

    【讨论】:

    • 最后一行 (y += vec(eye(3))) 改变 x,因为它等同于 y = y + vec(eye(3)),它分配了一个 new反对y
    • 你是对的@DavidP.Sanders;我的意思是把y[:] 放在lhs 上。固定。
    【解决方案2】:

    我猜以下内容可以完成这项工作:

    y = pointer_to_array( pointer( x, 10 ), (3,3) )   # make a slice starting from the 10th element
    

    这可以测试,例如

    x = zeros( 8 )
    p = pointer_to_array( pointer( x, 3 ), (3,2) )
    p[:,1] = 100.0
    p[:,2] = 200.0
    @show x    # => [ 0.0, 0.0, 100.0, 100.0, 100.0, 200.0, 200.0, 200.0 ]
    

    如果 x 的大小是切片大小的倍数,reshape() 也可以直接用于修改切片。例如,

    x = [ i for i=1:8 ]
    s = reshape( x, (2,2,2) )
    s[:,:,2] = 1000
    @show x      # => [1,2,3,4,1000,1000,1000,1000]
    

    【讨论】:

    • @warsaga 我对此进行了更多尝试,似乎没有新数组维度的边界检查(即“不安全”)github.com/JuliaLang/julia/blob/master/base/pointer.jl#L33 所以使用时请小心...我想知道是否可以为此使用其他(更安全的)方法(如子数组和数组视图)
    猜你喜欢
    • 2020-10-25
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多