我想在循环中使用selectperm
,根据矩阵每列中t
个最小元素的索引做一些事情(比如说t = 3
):
julia> a = rand(10, 10);
julia> for i in indices(a, 2)
println(selectperm(view(a, :, i), 1:3))
end
[9, 7, 6]
[3, 2, 6]
[8, 3, 1]
[4, 7, 6]
[4, 9, 10]
[6, 10, 8]
[10, 8, 9]
[10, 5, 6]
[1, 2, 9]
[5, 8, 10]
认为每次分配索引向量会更好地避免(实际上我不使用它们进行打印),我尝试使用预分配的数组作为结果 - 但是返回完全不同的值:
julia> cache = Vector{Int}(3);
julia> for i in indices(a, 2)
selectperm!(cache, view(a, :, i), 1:3)
println(cache)
end
[3, 1, 2]
[3, 2, 1]
[3, 1, 2]
[3, 1, 2]
[1, 3, 2]
[2, 1, 3]
[1, 2, 3]
[2, 1, 3]
[1, 2, 3]
[3, 2, 1]
那么,这里发生了什么?我如何正确使用selectperm!
?
答案 0 :(得分:0)
对于!
的函数而言,selectperm!
的“预分配索引向量”参数不存储结果的位置 - 或者至少,不仅如此。此参数在内部用于创建所有索引的部分permuatation,然后 subindexed 使用给定的k
参数描述您要选择的索引(在我们的案例1:3
中为三个最小的)。从code可以很容易地看出这一点。结果看起来合理但错在这里只是一个意外;以下内容会更具启发性:
julia> cache = Vector{Int}(3);
julia> for i in indices(a, 2)
selectperm!(cache, view(a, :, i), 4:6)
println(cache)
end
ERROR: BoundsError: attempt to access 3-element Array{Int64,1} at index [4:6]
Stacktrace: <...>
所以,为了在这里利用它,我们必须预先分配一个包含所有索引的向量(即a
列),然后该索引向量将是每次都是变换的。另外,传递initialized = true
可以避免每次填写索引。
julia> cache = collect(indices(a, 2));
julia> for i in indices(a, 2)
ix = selectperm!(cache, view(a, :, i), 1:3, initialized = true)
println(ix)
end
[9, 7, 6]
[3, 2, 6]
[8, 3, 1]
[4, 7, 6]
[4, 9, 10]
[6, 10, 8]
[10, 8, 9]
[10, 5, 6]
[1, 2, 9]
[5, 8, 10]