Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fortran-like arrays with arbitrary, zero or negative starting indices.

License

NotificationsYou must be signed in to change notification settings

JuliaArrays/OffsetArrays.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DocumentationBuild StatusCode coverageVersion

Introduction

OffsetArrays provides Julia users with arrays that have arbitraryindices, similar to those found in some other programming languageslike Fortran.

AnOffsetArray is a lightweight wrapper around anAbstractArray that shifts its indices.Generally, indexing into anOffsetArray should be as performant as the parent array.

Usage

There are two ways to constructOffsetArrays: by specifying the axes of the array, orby specifying its origin.

The first way to construct anOffsetArray by specifying its axes is:

OA=OffsetArray(A, axis1, axis2,...)

where you wantOA to have axes(axis1, axis2, ...) and be indexed by values thatfall within these axis ranges. Example:

julia>using OffsetArraysjulia> A=Float64.(reshape(1:15,3,5))3×5 Matrix{Float64}:1.04.07.010.013.02.05.08.011.014.03.06.09.012.015.0julia>axes(A)# indices of a Matrix start from 1 along each axis(Base.OneTo(3), Base.OneTo(5))julia> OA=OffsetArray(A,-1:1,0:4)# OA will have the axes (-1:1, 0:4)3×5OffsetArray(::Matrix{Float64},-1:1,0:4) with eltype Float64 with indices-1:1×0:4:1.04.07.010.013.02.05.08.011.014.03.06.09.012.015.0julia> OA[-1,0]1.0julia> OA[1,4]15.0

The second way to construct anOffsetArray is by specifying the origin, that is, the first indexalong each axis. This is particularly useful if one wants, eg., arrays that are 0-indexed as opposedto 1-indexed.

A convenient way to construct anOffsetArray this way is by usingOffsetArrays.Origin:

julia>using OffsetArrays: Originjulia>Origin(0)(A)# indices begin at 0 along all axes3×5OffsetArray(::Matrix{Float64},0:2,0:4) with eltype Float64 with indices0:2×0:4:1.04.07.010.013.02.05.08.011.014.03.06.09.012.015.0julia>Origin(2,3)(A)# indices begin at 2 along the first axis and 3 along the second3×5OffsetArray(::Matrix{Float64},2:4,3:7) with eltype Float64 with indices2:4×3:7:1.04.07.010.013.02.05.08.011.014.03.06.09.012.015.0

While the examples here refer to the common case where the parent arrays have indices starting at 1,this is not necessary. AnOffsetArray may wrap any array that has integer indices, irrespective ofwhere the indices begin.

How to go back to 1-indexed arrays

Certain libraries, such asLinearAlgebra, require arrays to be indexed from 1. Passing anOffsetArraywith shifted indices would lead to an error here.

julia> A=Float64.(reshape(1:16,4,4));julia> AO=Origin(0)(A);julia>using LinearAlgebrajulia>Diagonal(AO)ERROR: ArgumentError: offset arrays are not supported but got an array with index other than1

The way to obtain a1-indexed array from anOffsetArray is by usingOffsetArrays.no_offset_view.

An example of this is:

julia> OffsetArrays.no_offset_view(AO)4×4 Matrix{Float64}:1.05.09.013.02.06.010.014.03.07.011.015.04.08.012.016.0

This may now be passed toLinearAlgebra:

julia> D=Diagonal(OffsetArrays.no_offset_view(AO))4×4 Diagonal{Float64, Vector{Float64}}:1.06.011.016.0

If we want to restore the original indices ofAO, we may wrap anOffsetArray around theDiagonal as:

julia>Origin(AO)(D)4×4OffsetArray(::Diagonal{Float64, Vector{Float64}},0:3,0:3) with eltype Float64 with indices0:3×0:3:1.06.011.016.0

Here,Origin(AO) is able to automatically infer and use the indices ofAO.

Best practice on adopting OffsetArrays

For some applications, OffsetArrays give users an easy-to-understand interface. However, handlingthe non-conventional axes of OffsetArrays requires extra care. Otherwise, the code mighterror, crash, or return incorrect results. You can readthe Julialang documentation onoffset for more information. Herewe briefly summarize some of the best practices for users and package authors.

There is no need to support OffsetArrays for every function

You don't need to support offset arrays forinternal functions that only consume standard 1-basedarrays -- it doesn't change or improve anything.

You don't need to support offset arrays for functions thathave no well-defined behavior on customaxes. For instance, many linear algebra functions such as matrix multiplicationA * B does nothave an agreed behavior for offset arrays. In this case, it is a better practice to let users do theconversion.

The helper functionBase.require_one_based_indexing can be used to early check the axes and throwa meaningful error. If your interface functions do not intend to support offset arrays, we recommendyou add this check before starting the real computation.

useaxes instead ofsize/length

Many implementations assume the array axes start at 1 by writing loops such asfor i in 1:length(x) orfor i in 1:size(x, 1). A better practice is to usefor i in eachindex(x) orfor i in axes(x, 1) --axes provides more information thansize with no performance overhead.

Also, if you know what indices type you want to use,LinearIndices andCartesianIndices allow you to loop multidimensional arrays efficientlywithout worrying about the axes.

test against OffsetArrays

For package authors that declare support forAbstractArray, we recommend having a few test casesagainstOffsetArray to ensure the function works well for arrays with custom axes. This gives youmore confidence that users don't run into strange situations.

For package users that want to use offset arrays, many numerical correctness issues come from thefact that@inbounds is used inappropriately with the 1-based indexing assumption. Thus for debugpurposes, it is not a bad idea to start Julia with--check-bounds=yes, which turns all@inboundsinto a no-op and uncover potential out-of-bound errors.

About

Fortran-like arrays with arbitrary, zero or negative starting indices.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors35

Languages


[8]ページ先頭

©2009-2025 Movatter.jp