Skip to content

Commit 6f0e699

Browse files
authored
Add corresponding operate_to! method for Matrix-scalar product (#273)
1 parent c8a7d66 commit 6f0e699

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

src/dispatch.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,35 @@ end
468468
# +(::SparseMatrixCSC) is not defined for generic types in Base.
469469
Base.:+(A::AbstractArray{<:AbstractMutable}) = A
470470

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

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

482+
function operate_to!(
483+
output::AbstractArray,
484+
::typeof(*),
485+
v::AbstractArray,
486+
α::Union{Number,AbstractMutable},
487+
)
488+
return Base.broadcast!(*, output, v, α)
489+
end
490+
491+
function operate_to!(
492+
output::AbstractArray,
493+
::typeof(*),
494+
α::Union{Number,AbstractMutable},
495+
v::AbstractArray,
496+
)
497+
return Base.broadcast!(*, output, α, v)
498+
end
499+
475500
# Needed for Julia v1.0, otherwise, `broadcast(*, α, A)` gives a `Array` and
476501
# not a `Symmetric`.
477502

test/dispatch.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,24 @@ end
8585
@test 2im * B == C
8686
@test C isa Matrix{Complex{BigInt}}
8787
end
88+
89+
@testset "operate_to!(::Array, ::typeof(*), ::AbstractMutable, ::Array)" begin
90+
for A in ([1 2; 5 3], DummyBigInt[1 2; 5 3])
91+
for x in (2, DummyBigInt(2))
92+
# operate_to!(::Array, *, ::AbstractMutable, ::Array)
93+
B = x * A
94+
C = zero(B)
95+
D = MA.operate_to!(C, *, x, A)
96+
@test C === D
97+
@test typeof(B) == typeof(C)
98+
@test MA.isequal_canonical(B, C)
99+
# operate_to!(::Array, *, ::Array, ::AbstractMutable)
100+
B = A * x
101+
C = zero(B)
102+
D = MA.operate_to!(C, *, A, x)
103+
@test C === D
104+
@test typeof(B) == typeof(C)
105+
@test MA.isequal_canonical(B, C)
106+
end
107+
end
108+
end

0 commit comments

Comments
 (0)