Convenient creation of an OffsetArray?

I’ve been using OffsetArrays and is a bit frustrated with its cumbersome creation:

# xax[0:imax], zax[0:kmax] are OffsetArrays.
# I want to create an OffsetArray [0:imax, 0:kmax]
oa = OffsetArray(Array{Float64,2}(undef, length(xax), length(zax)), axes(xax,1), axes(zax,1))
# calculate values and assign them to oa . . . 

Is there a standard, easy solution?

If the eltype of the new array is the same as those of xax and zax and the new array is always 2D, then I could use a hack like

oa = xax * zax'

But, for other cases, it’s getting more and more cumbersome:

oa = Float64.(xax * reshape(yax, 1, axes(yax)) * reshape(zax, 1, 1, axes(zax)))

I do this a lot and so I wish I would be able to do something like

oa = OffsetArray{Float64,2}(undef, axes(xax,1), axes(zax,1))
# calculate values and assign them to oa . . .

It’s entirely possible (from my past experience with Julia) that I haven’t read the right documentation. If so, I apologize. I’m trying but I have found only this:

https://juliaarrays.github.io/OffsetArrays.jl/stable/

which seems to me to suggest that OffsetArray is always a wrapper to an existing “real” array.

This is already possible:

julia> oa = OffsetArray{Float64,2}(undef, 2:3, 2:3)
2×2 OffsetArray(::Matrix{Float64}, 2:3, 2:3) with eltype Float64 with indices 2:3×2:3:
 8.80086e199  2.64131e233
 2.58742e161  5.89012e-310
2 Likes

Thanks!!!

Is this a new feature? or is the documentation I looked at (see my initial message) is obsolete? or did I miss this feature in the documentation?

Again and again I fail to find the right documentation . . .


A tangent: I’m now trying to create a triangular or symmetric matrix but all examples in the official documentation indicate that you first create a square matrix and then the Symmetric object acts as a wrapper.

This time, I’ve experimented:

using LinearAlgebra
a = Symmetric{Float64,2}(undef, 3, 3) # or...(undef, 3)

which fails.

The constructor of this form is usually defined when you can create the array and then populate the elements. In Symmetric, you can’t set off-diagonal indices, so the constructor is not defined. In this case, the wrapper is the only route.

Perhaps the documentation needs to be improved to include such examples. This isn’t a new feature, but this doesn’t seem documented.

Would you care to elaborate? I don’t understand “set off-diagonal indices”.