gpt4 book ai didi

arrays - 类似 Fortran 的数组,例如 Julia 中的 FArray(Float64, -1 :1, -7 :7, -128:512)

转载 作者:行者123 更新时间:2023-12-04 01:10:28 24 4
gpt4 key购买 nike

通常,对于 Julia 使用基于 1 的数组是一个不错的决定,但有时希望拥有类似 Fortran 的数组,其索引跨越 ℤ 的某些子范围:

julia> x = FArray(Float64, -1:1,-7:7,-128:512)

有用的地方:

在教授所著的《双曲偏微分方程的数值解》一书随附的代码中。 John A. Tragenstein 这些负指数被大量用于边界条件的鬼细胞。
教授的 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

输出:
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] =
...

由于我对 Julia 完全陌生,因此将不胜感激任何建议,尤其是能够提高效率的建议。

[编辑]

该主题已在此处讨论:

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

请注意,未完全检查边界更多详细信息在这里:
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])

获取索引和设置索引! 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

最佳答案

现在有两个包提供这种功能。对于具有任意起始索引的数组,请参阅 https://github.com/alsam/OffsetArrays.jl .如需更多灵活性,请参阅 https://github.com/mbauman/AxisArrays.jl ,其中索引不必是整数。

关于arrays - 类似 Fortran 的数组,例如 Julia 中的 FArray(Float64, -1 :1, -7 :7, -128:512),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20428078/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com