m20*_*022 4 arrays indexing julia
来自 R,我对 Julia 语言比较陌生。
有时我会遇到这样一种情况,我想在同一个命令中使用两次索引:首先使用一组下标,然后使用线性索引。如:
array = zeros(3, 3, 3)
array[:, :, 2][9] = 999
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,朱莉娅通过返回答案来回应:
julia> array[:, :, 2][9] = 999
999
Run Code Online (Sandbox Code Playgroud)
但是,原始数组不变:
julia> array[:, :, 2]
3×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
Run Code Online (Sandbox Code Playgroud)
这是一个错误,还是有一些关于我缺少的语言的事实来解释它为什么会这样?
用
@views array[:, :, 2][9] = 999
Run Code Online (Sandbox Code Playgroud)
这里要知道的是,无论是什么,它都x[1] = y被降低为对 的单个函数调用。这是一个普通函数,因此它的所有参数都在调用该函数之前进行评估。您可以通过以下方式查看正在执行的操作:setindex!x
julia> set1(x) = x[1] = 33
set1 (generic function with 1 method)
julia> @code_lowered set1(zeros(3))
CodeInfo(
1 ? Base.setindex!(x, 33, 1)
??? return 33
)
julia> :( z[1,:][2] ) # the brackets show precedence, else try |> dump
:((z[1, :])[2])
julia> set2(z) = z[1,:][2] = 3^4;
julia> @code_lowered set2(zeros(2,3))
CodeInfo(
1 ? %1 = Core.apply_type(Base.Val, 4)
? %2 = (%1)()
? %3 = Base.literal_pow(Main.:^, 3, %2)
? %4 = Base.getindex(z, 1, Main.:(:))
? Base.setindex!(%4, %3, 2)
??? return %3
)
Run Code Online (Sandbox Code Playgroud)
Whenx是另一个索引表达式,这只是函数调用getindex(z,1,:)。这会创建一个副本,并setindex!写入副本,然后返回其右侧(临时变量%3,包含3^4)。副本永远不会逃脱。
获得您想要的行为的方法是x通过编写view(z,1,:)[2] = 33或创建视图而不是副本:
julia> set3(z) = @views z[1,:][2] = 33;
julia> @code_lowered set3(zeros(2,3))
CodeInfo(
1 ? %1 = (Base.maybeview)(x, 1, Main.:(:))
? Base.setindex!(%1, 33, 2)
??? return 33
)
julia> z3 = zeros(2,3);
julia> set3(z3)
33
julia> z3
2×3 Matrix{Float64}:
0.0 33.0 0.0
0.0 0.0 0.0
Run Code Online (Sandbox Code Playgroud)
肯定可以降低z[1,:][2] = 3到其他东西,比如multi_setindex!(z, 3, (1,:), (2,))也许是某种功能。我想这被认为过于复杂。
我认为 R 具有非标准评估,在这种评估下,函数可以在评估之前访问其参数,但 Julia 不允许这样做。它确实有宏(总是用 表示@),可以在计算之前对输入语法进行操作。这是@views工作所必需的,当然也是@code_lowered为了看到33或以外的东西9。
| 归档时间: |
|
| 查看次数: |
68 次 |
| 最近记录: |