diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 9d050094..cd8f6ac1 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -1,6 +1,8 @@ module OffsetArrays using Base: Indices, tail, @propagate_inbounds +import Base: (*), convert, promote_rule + @static if !isdefined(Base, :IdentityUnitRange) const IdentityUnitRange = Base.Slice else @@ -45,10 +47,12 @@ OffsetArray(A::AbstractArray{T,N}, offsets::Vararg{Int,N}) where {T,N} = OffsetArray(A, offsets) OffsetArray(A::AbstractArray{T,0}) where {T} = OffsetArray(A, ()) +# Create an uninitialized OffsetArray with given element type const ArrayInitializer = Union{UndefInitializer, Missing, Nothing} OffsetArray{T,N}(init::ArrayInitializer, inds::Indices{N}) where {T,N} = OffsetArray(Array{T,N}(init, map(indexlength, inds)), map(indexoffset, inds)) OffsetArray{T}(init::ArrayInitializer, inds::Indices{N}) where {T,N} = OffsetArray{T,N}(init, inds) +# Same thing, but taking multiple args for offsets/indices OffsetArray{T,N}(init::ArrayInitializer, inds::Vararg{AbstractUnitRange,N}) where {T,N} = OffsetArray{T,N}(init, inds) OffsetArray{T}(init::ArrayInitializer, inds::Vararg{AbstractUnitRange,N}) where {T,N} = OffsetArray{T,N}(init, inds) @@ -403,6 +407,28 @@ end no_offset_view(A::OffsetArray) = no_offset_view(parent(A)) +# Quick hack for matrix multiplication. +# Ideally, one would instead improve LinearAlgebra's support of custom indexing. +function (*)(A::OffsetMatrix, B::OffsetMatrix) + matmult_check_axes(A, B) + C = OffsetArray(parent(A) * parent(B), (axes(A,1), axes(B,2))) +end + +function (*)(A::OffsetMatrix, B::OffsetVector) + matmult_check_axes(A, B) + C = OffsetArray(parent(A) * parent(B), axes(A,1)) +end +matmult_check_axes(A, B) = axes(A, 2) == axes(B, 1) || error("axes(A,2) must equal axes(B,1)") + +(*)(A::OffsetMatrix, B::AbstractMatrix) = A * OffsetArray(B) +(*)(A::OffsetMatrix, B::AbstractVector) = A * OffsetArray(B) +(*)(A::AbstractMatrix, B::OffsetArray) = OffsetArray(A) * B +(*)(A::AbstractVector, B::OffsetArray) = OffsetArray(A) * B + +# An alternative to the above four methods would be to use promote_rule, but it doesn't get invoked +# promote_rule(::Type{A1}, ::Type{A2}) where A1<:AbstractArray{<:Any,N} where A2<:OffsetArray{<:Any,N,A3} where {N,A3} = OffsetArray{eltype(promote_type(A1, A3)), N, promote_type(A1, A3)} + + #### # work around for segfault in searchsorted* # https://github.com/JuliaLang/julia/issues/33977