|
1 | 1 | module OffsetArrays
|
2 | 2 |
|
3 | 3 | using Base: Indices, tail, @propagate_inbounds
|
| 4 | +import Base: (*), convert, promote_rule |
| 5 | + |
4 | 6 | @static if !isdefined(Base, :IdentityUnitRange)
|
5 | 7 | const IdentityUnitRange = Base.Slice
|
6 | 8 | else
|
@@ -45,10 +47,12 @@ OffsetArray(A::AbstractArray{T,N}, offsets::Vararg{Int,N}) where {T,N} =
|
45 | 47 | OffsetArray(A, offsets)
|
46 | 48 | OffsetArray(A::AbstractArray{T,0}) where {T} = OffsetArray(A, ())
|
47 | 49 |
|
| 50 | +# Create an uninitialized OffsetArray with given element type |
48 | 51 | const ArrayInitializer = Union{UndefInitializer, Missing, Nothing}
|
49 | 52 | OffsetArray{T,N}(init::ArrayInitializer, inds::Indices{N}) where {T,N} =
|
50 | 53 | OffsetArray(Array{T,N}(init, map(indexlength, inds)), map(indexoffset, inds))
|
51 | 54 | OffsetArray{T}(init::ArrayInitializer, inds::Indices{N}) where {T,N} = OffsetArray{T,N}(init, inds)
|
| 55 | +# Same thing, but taking multiple args for offsets/indices |
52 | 56 | OffsetArray{T,N}(init::ArrayInitializer, inds::Vararg{AbstractUnitRange,N}) where {T,N} = OffsetArray{T,N}(init, inds)
|
53 | 57 | OffsetArray{T}(init::ArrayInitializer, inds::Vararg{AbstractUnitRange,N}) where {T,N} = OffsetArray{T,N}(init, inds)
|
54 | 58 |
|
|
403 | 407 | no_offset_view(A::OffsetArray) = no_offset_view(parent(A))
|
404 | 408 |
|
405 | 409 |
|
| 410 | +# Quick hack for matrix multiplication. |
| 411 | +# Ideally, one would instead improve LinearAlgebra's support of custom indexing. |
| 412 | +function (*)(A::OffsetMatrix, B::OffsetMatrix) |
| 413 | + matmult_check_axes(A, B) |
| 414 | + C = OffsetArray(parent(A) * parent(B), (axes(A,1), axes(B,2))) |
| 415 | +end |
| 416 | + |
| 417 | +function (*)(A::OffsetMatrix, B::OffsetVector) |
| 418 | + matmult_check_axes(A, B) |
| 419 | + C = OffsetArray(parent(A) * parent(B), axes(A,1)) |
| 420 | +end |
| 421 | +matmult_check_axes(A, B) = axes(A, 2) == axes(B, 1) || error("axes(A,2) must equal axes(B,1)") |
| 422 | + |
| 423 | +(*)(A::OffsetMatrix, B::AbstractMatrix) = A * OffsetArray(B) |
| 424 | +(*)(A::OffsetMatrix, B::AbstractVector) = A * OffsetArray(B) |
| 425 | +(*)(A::AbstractMatrix, B::OffsetArray) = OffsetArray(A) * B |
| 426 | +(*)(A::AbstractVector, B::OffsetArray) = OffsetArray(A) * B |
| 427 | + |
| 428 | +# An alternative to the above four methods would be to use promote_rule, but it doesn't get invoked |
| 429 | +# 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)} |
| 430 | + |
| 431 | + |
406 | 432 | ####
|
407 | 433 | # work around for segfault in searchsorted*
|
408 | 434 | # https://github.com/JuliaLang/julia/issues/33977
|
|
0 commit comments