一般来说,Julia的基于1的数组是一个很好的决定,但有时候希望有类似Fortran的数组,其索引跨越some的某些子范围:
julia> x = FArray(Float64, -1:1,-7:7,-128:512)
Run Code Online (Sandbox Code Playgroud)
哪里有用:
在教程中伴随着"双曲偏微分方程的数值解"一书的代码中.John A. Trangenstein这些负指数被强烈用于鬼细胞的边界条件.对于Clawpack(代表"保护法律包"),教授也是如此.Randall J. LeVeque http://depts.washington.edu/clawpack/ 还有许多其他代码,这些指数很自然.因此,这种辅助类对于快速翻译这些代码是有用的.
我刚开始实施这样一种辅助类型,但由于我对Julia很新,所以我非常感谢你的帮助.
我开始时:
type FArray
ranges
array::Array
function FArray(T, r::Range1{Int}...)
dims = map((x) -> length(x), r)
array = Array(T, dims)
new(r, array)
end
end
Run Code Online (Sandbox Code Playgroud)
输出:
julia> include ("FortranArray.jl")
julia> x = FArray(Float64, -1:1,-7:7,-128:512)
FArray((-1:1,-7:7,-128:512),3x15x641 Array{Float64,3}:
[:, :, 1] =
6.90321e-310 2.6821e-316 1.96042e-316 0.0 0.0 0.0 9.84474e-317 … 1.83233e-316 2.63285e-316 0.0 9.61618e-317 0.0
6.90321e-310 6.32404e-322 2.63285e-316 0.0 0.0 0.0 2.63292e-316 2.67975e-316
...
[:, :, 2] =
...
Run Code Online (Sandbox Code Playgroud)
因为我对朱莉娅来说是全新的,所以任何能够提高效率的建议都会受到高度赞赏.
[编辑]
这里讨论的主题是:
https://groups.google.com/forum/#!topic/julia-dev/NOF6MA6tb9Y
在讨论期间,阐述了两种具有任意基础的Julia数组的方法:基于SubArray,样本用法带有辅助函数:
function farray(T, r::Range1{Int64}...)
dims = map((x) -> length(x), r)
array = Array(T, dims)
sub_indices = map((x) -> -minimum(x) + 2 : maximum(x), r)
sub(array, sub_indices)
end
julia> y[-1,-7,-128] = 777
777
julia> y[-1,-7,-128] + 33
810.0
julia> y[-2,-7,-128]
ERROR: BoundsError()
in getindex at subarray.jl:200
julia> y[2,-7,-128]
2.3977385e-316
Run Code Online (Sandbox Code Playgroud)
请注意,这些边界没有完全检查更多细节在这里:https: //github.com/JuliaLang/julia/issues/4044
目前,SubArray存在性能问题但最终其性能可能会有所改善,另请参阅:
https://github.com/JuliaLang/julia/issues/5117
https://github.com/JuliaLang/julia/issues/3496
除了检查两个边界之外,另一种目前具有更好性能的方法:
type FArray{T<:Number, N, A<:AbstractArray} <: AbstractArray
ranges
offsets::NTuple{N,Int}
array::A
function FArray(r::Range1{Int}...)
dims = map((x) -> length(x), r)
array = Array(T, dims)
offs = map((x) -> 1 - minimum(x), r)
new(r, offs, array)
end
end
FArray(T, r::Range1{Int}...) = FArray{T, length(r,), Array{T, length(r,)}}(r...)
getindex{T<:Number}(FA::FArray{T}, i1::Int) = FA.array[i1+FA.offsets[1]]
getindex{T<:Number}(FA::FArray{T}, i1::Int, i2::Int) = FA.array[i1+FA.offsets[1], i2+FA.offsets[2]]
getindex{T<:Number}(FA::FArray{T}, i1::Int, i2::Int, i3::Int) = FA.array[i1+FA.offsets[1], i2+FA.offsets[2], i3+FA.offsets[3]]
setindex!{T}(FA::FArray{T}, x, i1::Int) = arrayset(FA.array, convert(T,x), i1+FA.offsets[1])
setindex!{T}(FA::FArray{T}, x, i1::Int, i2::Int) = arrayset(FA.array, convert(T,x), i1+FA.offsets[1], i2+FA.offsets[2])
setindex!{T}(FA::FArray{T}, x, i1::Int, i2::Int, i3::Int) = arrayset(FA.array, convert(T,x), i1+FA.offsets[1], i2+FA.offsets[2], i3+FA.offsets[3])
Run Code Online (Sandbox Code Playgroud)
getindex和setindex!FArray的方法受base/array.jl代码的启发.
用例:
julia> y = FArray(Float64, -1:1,-7:7,-128:512);
julia> y[-1,-7,-128] = 777
777
julia> y[-1,-7,-128] + 33
810.0
julia> y[-1,2,3]
0.0
julia> y[-2,-7,-128]
ERROR: BoundsError()
in getindex at FortranArray.jl:27
julia> y[2,-7,-128]
ERROR: BoundsError()
in getindex at FortranArray.jl:27
Run Code Online (Sandbox Code Playgroud)
现在有两个包提供这种功能.对于具有任意起始索引的数组,请参阅https://github.com/alsam/OffsetArrays.jl.有关更多灵活性,请参阅https://github.com/mbauman/AxisArrays.jl,其中索引不必是整数.
| 归档时间: |
|
| 查看次数: |
536 次 |
| 最近记录: |