Skip to content

Commit 983f6ec

Browse files
authored
Add adhoc arithmetics for FreeAssociativeAlgebraElem (#1866)
* Add adhoc arithmetics for FreeAssociativeAlgebraElem * Add more coercions * Address comment * Add and use `mul(::FreeAssAlgElem, ::FreeAssAlgElem, ::Coeffs)
1 parent 5ffdd2d commit 983f6ec

File tree

2 files changed

+106
-3
lines changed

2 files changed

+106
-3
lines changed

src/generic/FreeAssociativeAlgebra.jl

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,14 @@ function (a::FreeAssociativeAlgebra{T})(b::T) where T
133133
return FreeAssociativeAlgebraElem{T}(a, T[b], [Int[]], 1)
134134
end
135135

136-
function (a::FreeAssociativeAlgebra{T})(b::Integer) where T
137-
iszero(b) && return zero(a)
136+
function (a::FreeAssociativeAlgebra{T})(b::Union{Integer, Rational, AbstractFloat}) where T
138137
R = base_ring(a)
139-
return FreeAssociativeAlgebraElem{T}(a, T[R(b)], [Int[]], 1)
138+
return a(R(b))
139+
end
140+
141+
function (a::FreeAssociativeAlgebra{T})(b::T) where {T <: Union{Integer, Rational, AbstractFloat}}
142+
iszero(b) && return zero(a)
143+
return FreeAssociativeAlgebraElem{T}(a, T[b], [Int[]], 1)
140144
end
141145

142146
function (a::FreeAssociativeAlgebra{T})(b::FreeAssociativeAlgebraElem{T}) where T <: RingElement
@@ -633,6 +637,20 @@ end
633637
#
634638
###############################################################################
635639

640+
function *(a::FreeAssociativeAlgebraElem, n::Union{Integer, Rational, AbstractFloat})
641+
z = zero(a)
642+
return mul!(z, a, n)
643+
end
644+
645+
function *(a::FreeAssociativeAlgebraElem{T}, n::T) where {T <: RingElem}
646+
z = zero(a)
647+
return mul!(z, a, n)
648+
end
649+
650+
*(n::Union{Integer, Rational, AbstractFloat}, a::FreeAssociativeAlgebraElem) = a*n
651+
652+
*(n::T, a::FreeAssociativeAlgebraElem{T}) where {T <: RingElem} = a*n
653+
636654
function divexact(
637655
a::FreeAssociativeAlgebraElem{T},
638656
b::Integer;
@@ -786,6 +804,33 @@ function sub!(z::FreeAssociativeAlgebraElem{T}, a::FreeAssociativeAlgebraElem{T}
786804
return z
787805
end
788806

807+
function mul!(a::FreeAssociativeAlgebraElem{T}, n::Union{Integer, Rational, AbstractFloat, T}) where T <: RingElement
808+
for i in 1:length(a)
809+
a.coeffs[i] = mul!(a.coeffs[i], n)
810+
end
811+
return a
812+
end
813+
814+
function mul!(z::FreeAssociativeAlgebraElem{T}, a::FreeAssociativeAlgebraElem{T}, n::Union{Integer, Rational, AbstractFloat, T}) where T <: RingElement
815+
if z === a
816+
return mul!(a, n)
817+
end
818+
fit!(z, length(a))
819+
j = 1
820+
for i = 1:length(a)
821+
if isassigned(z.coeffs, j)
822+
z.coeffs[j] = mul!(z.coeffs[j], a.coeffs[i], n)
823+
else
824+
z.coeffs[j] = a.coeffs[i] * n
825+
end
826+
if !iszero(z.coeffs[j])
827+
z.exps[j] = a.exps[i]
828+
j += 1
829+
end
830+
end
831+
z.length = j - 1
832+
return z
833+
end
789834

790835
################################################################################
791836
#

test/generic/FreeAssociativeAlgebra-test.jl

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,64 @@ end
216216
end
217217
end
218218

219+
@testset "Generic.FreeAssociativeAlgebra.adhoc_binary" begin
220+
R, x = ZZ["y"]
221+
222+
for num_vars = 1:10
223+
var_names = ["x$j" for j in 1:num_vars]
224+
225+
S, varlist = free_associative_algebra(R, var_names)
226+
227+
for iter = 1:100
228+
f = rand(S, 0:5, 0:100, 0:0, -100:100)
229+
230+
d1 = rand(-20:20)
231+
d2 = rand(-20:20)
232+
g1 = rand(R, 0:2, -10:10)
233+
g2 = rand(R, 0:2, -10:10)
234+
235+
@test f*d1 + f*d2 == (d1 + d2)*f
236+
@test f*BigInt(d1) + f*BigInt(d2) == (BigInt(d1) + BigInt(d2))*f
237+
@test f*g1 + f*g2 == (g1 + g2)*f
238+
239+
@test f + d1 + d2 == d1 + d2 + f
240+
@test f + BigInt(d1) + BigInt(d2) == BigInt(d1) + BigInt(d2) + f
241+
@test f + g1 + g2 == g1 + g2 + f
242+
243+
@test f - d1 - d2 == -((d1 + d2) - f)
244+
@test f - BigInt(d1) - BigInt(d2) == -((BigInt(d1) + BigInt(d2)) - f)
245+
@test f - g1 - g2 == -((g1 + g2) - f)
246+
247+
@test f + d1 - d1 == f
248+
@test f + BigInt(d1) - BigInt(d1) == f
249+
@test f + g1 - g1 == f
250+
251+
if !iszero(d1)
252+
@test divexact(d1 * f, d1) == f
253+
@test divexact(d1 * f, BigInt(d1)) == f
254+
end
255+
end
256+
end
257+
258+
S, (x,y) = free_associative_algebra(QQ, [:x, :y])
259+
f = x^2 + x*y^2*x + QQ(5)*y - QQ(1//2)*y*x
260+
261+
@test 2 + f == QQ(2) + f
262+
@test f + 2 == f + QQ(2)
263+
@test 1//2 + f == QQ(1//2) + f
264+
@test f + 1//2 == f + QQ(1//2)
265+
266+
@test 2 - f == QQ(2) - f
267+
@test f - 2 == f - QQ(2)
268+
@test 1//2 - f == QQ(1//2) - f
269+
@test f - 1//2 == f - QQ(1//2)
270+
271+
@test 2 * f == QQ(2) * f
272+
@test f * 2 == f * QQ(2)
273+
@test 1//2 * f == QQ(1//2) * f
274+
@test f * 1//2 == f * QQ(1//2)
275+
end
276+
219277
@testset "Generic.FreeAssociativeAlgebra.NCRing_interface" begin
220278
S, = free_associative_algebra(ZZ, 3)
221279
test_NCRing_interface(S)

0 commit comments

Comments
 (0)