Skip to content

Commit

Permalink
Merge pull request #56 from JuliaAlgebra/mk/multiplication
Browse files Browse the repository at this point in the history
add "monomial" multiplication
  • Loading branch information
kalmarek authored Jul 5, 2024
2 parents f998c9f + 7a0232e commit ba3697f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 21 deletions.
39 changes: 29 additions & 10 deletions src/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,24 @@ end
function MA.promote_operation(::typeof(*), ::Type{T}, ::Type{A}) where {T<:Number, A<:AlgebraElement}
return algebra_promote_operation(*, A, T)
end
function Base.:*(a::Number, X::AlgebraElement)
return MA.operate_to!(_preallocate_output(*, X, a), *, X, a)
function Base.:*(a::Any, X::AlgebraElement)
return MA.operate_to!(_preallocate_output(*, X, a), *, a, X)
end
function Base.:div(X::AlgebraElement, a::Number)
return MA.operate_to!(_preallocate_output(div, X, a), div, X, a)
end
function Base.:*(
a::T,
X::AlgebraElement{A},
) where {T,O,A<:AbstractStarAlgebra{O,T}}
return MA.operate_to!(similar(X), __lmul, a, X)
end
function Base.:*(
X::AlgebraElement{A},
a::T,
) where {T,O,A<:AbstractStarAlgebra{O,T}}
return MA.operate_to!(similar(X), __rmul, a, X)
end

for op in [:+, :-, :*]
@eval begin
Expand Down Expand Up @@ -64,11 +76,11 @@ end
function MA.operate_to!(
res::AlgebraElement,
::typeof(*),
a::Any,
X::AlgebraElement,
a::Number,
)
@assert parent(res) === parent(X)
MA.operate_to!(coeffs(res), *, coeffs(X), a)
MA.operate_to!(coeffs(res), *, a, coeffs(X))
return res
end

Expand All @@ -83,6 +95,17 @@ function MA.operate_to!(
return res
end

function MA.operate_to!(
res::AlgebraElement,
mul::Union{typeof(__lmul),typeof(__rmul)},
a,
X::AlgebraElement,
)
@assert parent(res) == parent(X)
MA.operate_to!(coeffs(res), mul, a, coeffs(X))
return res
end

function MA.operate_to!(res::AlgebraElement, ::typeof(-), X::AlgebraElement)
@assert parent(res) === parent(X)
MA.operate_to!(coeffs(res), -, coeffs(X))
Expand Down Expand Up @@ -118,9 +141,7 @@ function MA.operate_to!(
args::Vararg{AlgebraElement,N},
) where {N}
for arg in args
if arg isa AlgebraElement
@assert parent(res) == parent(arg)
end
@assert parent(res) == parent(arg)
end
mstr = mstructure(basis(res))
MA.operate_to!(coeffs(res), mstr, coeffs.(args)...)
Expand All @@ -133,9 +154,7 @@ function MA.operate!(
args::Vararg{AlgebraElement,N},
) where {N}
for arg in args
if arg isa AlgebraElement
@assert parent(res) == parent(arg)
end
@assert parent(res) == parent(arg)
end
mstr = mstructure(basis(res))
MA.operate!(UnsafeAddMul(mstr), coeffs(res), coeffs.(args)...)
Expand Down
32 changes: 27 additions & 5 deletions src/coefficients.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,12 @@ end

Base.zero(X::AbstractCoefficients) = MA.operate!(zero, similar(X))
Base.:-(X::AbstractCoefficients) = MA.operate_to!(__prealloc(X, -1, *), -, X)
Base.:*(a::Number, X::AbstractCoefficients) = X * a
Base.:/(X::AbstractCoefficients, a::Number) = X * inv(a)
Base.:*(X::AbstractCoefficients, a::Any) = a * X
Base.:/(X::AbstractCoefficients, a::Number) = inv(a) * X
Base.://(X::AbstractCoefficients, a::Number) = X * 1 // a

function Base.:*(X::AbstractCoefficients, a::Number)
return MA.operate_to!(__prealloc(X, a, *), *, X, a)
function Base.:*(a::Any, X::AbstractCoefficients)
return MA.operate_to!(__prealloc(X, a, *), *, a, X)
end
function Base.:div(X::AbstractCoefficients, a::Number)
return MA.operate_to!(__prealloc(X, a, div), div, X, a)
Expand Down Expand Up @@ -167,8 +167,8 @@ end
function MA.operate_to!(
res::AbstractCoefficients,
::typeof(*),
a::Any,
X::AbstractCoefficients,
a::Number,
)
if res !== X
MA.operate!(zero, res)
Expand Down Expand Up @@ -240,3 +240,25 @@ function MA.operate_to!(
end
return res
end

__lmul(a, k) = a * k
__rmul(a, k) = k * a

function MA.operate_to!(
res::AbstractCoefficients,
mul::Union{typeof(__lmul),typeof(__rmul)},
a,
X::AbstractCoefficients,
)
if res === X
throw("No aliasing is allowed in shift")
else
MA.operate!(zero, res)
for (k, v) in nonzero_pairs(X)
res[mul(a, k)] += v
end
end
return res
end


6 changes: 6 additions & 0 deletions test/abstract_coeffs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,10 @@
@test norm(fP2m) == norm(P2m) == norm(fP2m)
v = coeffs(P2m, basis(fRG)) # an honest vector
@test dot(fP2m, fP2m) == dot(coeffs(fP2m), v) == dot(v, coeffs(fP2m))

s1, s2 = PermutationGroups.gens(G)
@assert s1 * s2 s2 * s1
Z = RG(1) + RG(s1)
@test s2 * Z == RG(s2) + RG(s2 * s1)
@test Z * s2 == RG(s2) + RG(s1 * s2)
end
12 changes: 6 additions & 6 deletions test/monoid_algebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@
@test coeffs(Z) == coeffs(fZ, basis(RG))
@test coeffs(fZ) == coeffs(Z, basis(fRG))

@test coeffs(2 * X * Y) == coeffs(MA.operate_to!(Z, *, Z, 2))
@test coeffs(2 * fX * fY) == coeffs(MA.operate_to!(fZ, *, fZ, 2))
@test coeffs(2 * X * Y) == coeffs(MA.operate_to!(Z, *, 2, Z))
@test coeffs(2 * fX * fY) == coeffs(MA.operate_to!(fZ, *, 2, fZ))
end
end
@testset "mutable arithmetic" begin
Expand Down Expand Up @@ -118,19 +118,19 @@
end

let d = deepcopy(a)
MA.operate_to!(d, *, a, 2)
MA.operate_to!(d, *, 2, a)
@test d == 2a
MA.operate_to!(d, *, d, 2)
MA.operate_to!(d, *, 2, d)
@test d == 4a
MA.operate_to!(d, *, a, b)
@test d == a * b
@test_throws ArgumentError MA.operate_to!(d, *, d, b)

d = deepcopy(a)
@test @allocated(MA.operate_to!(d, *, d, 2)) == 0
@test @allocated(MA.operate_to!(d, *, 2, d)) == 0
@test d == 2a

@test @allocated(MA.operate_to!(d, *, a, 2)) == 0
@test @allocated(MA.operate_to!(d, *, 2, a)) == 0
@test d == 2a

MA.operate!(zero, d)
Expand Down

0 comments on commit ba3697f

Please sign in to comment.