Skip to content

Commit

Permalink
Add corresponding operate_to! method for Matrix-scalar product (#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
blegat authored Apr 17, 2024
1 parent c8a7d66 commit 6f0e699
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/dispatch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -468,10 +468,35 @@ end
# +(::SparseMatrixCSC) is not defined for generic types in Base.
Base.:+(A::AbstractArray{<:AbstractMutable}) = A

# `Base.*(::AbstractArray, α)` is only defined if `α isa Number`
# Currently, mutable types are scalar elements (e.g. JuMP expression,
# MOI functions or polynomials) so broadcasting is the right dispatch.
# If this causes issues in the future, e.g., because a user define a non-scalar
# subtype of `AbstractMutable`, we might want to check that
# `ndims` is zero and error otherwise.

Base.:*::AbstractMutable, A::AbstractArray) = α .* A

Base.:*(A::AbstractArray, α::AbstractMutable) = A .* α

function operate_to!(
output::AbstractArray,
::typeof(*),
v::AbstractArray,
α::Union{Number,AbstractMutable},
)
return Base.broadcast!(*, output, v, α)
end

function operate_to!(
output::AbstractArray,
::typeof(*),
α::Union{Number,AbstractMutable},
v::AbstractArray,
)
return Base.broadcast!(*, output, α, v)
end

# Needed for Julia v1.0, otherwise, `broadcast(*, α, A)` gives a `Array` and
# not a `Symmetric`.

Expand Down
21 changes: 21 additions & 0 deletions test/dispatch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,24 @@ end
@test 2im * B == C
@test C isa Matrix{Complex{BigInt}}
end

@testset "operate_to!(::Array, ::typeof(*), ::AbstractMutable, ::Array)" begin
for A in ([1 2; 5 3], DummyBigInt[1 2; 5 3])
for x in (2, DummyBigInt(2))
# operate_to!(::Array, *, ::AbstractMutable, ::Array)
B = x * A
C = zero(B)
D = MA.operate_to!(C, *, x, A)
@test C === D
@test typeof(B) == typeof(C)
@test MA.isequal_canonical(B, C)
# operate_to!(::Array, *, ::Array, ::AbstractMutable)
B = A * x
C = zero(B)
D = MA.operate_to!(C, *, A, x)
@test C === D
@test typeof(B) == typeof(C)
@test MA.isequal_canonical(B, C)
end
end
end

0 comments on commit 6f0e699

Please sign in to comment.