Skip to content

Commit 0529fe8

Browse files
committed
use offsets instead of axes
1 parent f34598c commit 0529fe8

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

src/OffsetArrays.jl

+10-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
module OffsetArrays
22

33
using Base: Indices, tail, @propagate_inbounds
4-
import Base: (*), convert, promote_rule
54

65
@static if !isdefined(Base, :IdentityUnitRange)
76
const IdentityUnitRange = Base.Slice
@@ -406,28 +405,23 @@ end
406405

407406
no_offset_view(A::OffsetArray) = no_offset_view(parent(A))
408407

409-
410408
# Quick hack for matrix multiplication.
411409
# Ideally, one would instead improve LinearAlgebra's support of custom indexing.
412-
function (*)(A::OffsetMatrix, B::OffsetMatrix)
410+
function Base.:(*)(A::OffsetMatrix, B::OffsetMatrix)
413411
matmult_check_axes(A, B)
414-
C = OffsetArray(parent(A) * parent(B), (axes(A,1), axes(B,2)))
412+
C = parent(A) * parent(B)
413+
OffsetArray{eltype(C), 2, typeof(C)}(C, (A.offsets[1], B.offsets[2]))
415414
end
416415

417-
function (*)(A::OffsetMatrix, B::OffsetVector)
416+
function Base.:(*)(A::OffsetMatrix, B::OffsetVector)
418417
matmult_check_axes(A, B)
419-
C = OffsetArray(parent(A) * parent(B), axes(A,1))
418+
C = parent(A) * parent(B)
419+
OffsetArray{eltype(C), 1, typeof(C)}(C, (A.offsets[1], ))
420+
end
421+
function matmult_check_axes(A, B)
422+
axes(A, 2) === axes(B, 1) || axes(A, 2) == axes(B, 1) ||
423+
error("axes(A,2) = $(UnitRange(axes(A,2))) does not equal axes(B,1) = $(UnitRange(axes(B,1)))")
420424
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-
431425

432426
####
433427
# work around for segfault in searchsorted*

test/runtests.jl

+31
Original file line numberDiff line numberDiff line change
@@ -946,3 +946,34 @@ end
946946
@test searchsorted(o, 5) == 2:2
947947
@test searchsorted(o, 6) == 3:2
948948
end
949+
950+
@testset "Matrix multiplication" begin
951+
a = [1 2; 3 4]
952+
v = [5, 6]
953+
oa = OffsetArray(a, (2, 2))
954+
ov = OffsetVector(v, (2,))
955+
956+
@test parent(oa * oa) == a * a
957+
@test axes(oa * oa) == axes(oa)
958+
959+
@test parent(oa * ov) == a * v
960+
@test axes(oa * ov) == (axes(oa, 1),)
961+
962+
@test parent(ones(2, 2:3) * ones(2:3, 3:5)) == ones(2, 2) * ones(2, 3)
963+
@test axes(ones(2, 2:3) * ones(2:3, 3:5)) == (1:2, 3:5)
964+
965+
@test parent(ones(2, 2:3) * ones(2:3)) == ones(2, 2) * ones(2)
966+
@test axes(ones(2, 2:3) * ones(2:3)) == (1:2,)
967+
968+
# One-based arrays
969+
oa2 = OffsetArray(a, axes(a))
970+
@test oa2 * a == a * a
971+
@test a * oa2 == a * a
972+
973+
@test oa2 * v == a * v
974+
@test v' * oa2 == v' * a
975+
976+
@test_throws Exception zeros(2, 2:3) * zeros(2:4, 2)
977+
@test_throws Exception zeros(2, 2:3) * zeros(3:4, 2)
978+
@test_throws Exception zeros(2, 2:3) * zeros(2:4)
979+
end

0 commit comments

Comments
 (0)