diff --git a/.gitignore b/.gitignore index de729c50ba..eccb96a625 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /docs/build/ Manifest.toml +LocalPreferences.toml .DS_Store diff --git a/src/AbstractAlgebra.jl b/src/AbstractAlgebra.jl index eae2458e0f..199c6de967 100644 --- a/src/AbstractAlgebra.jl +++ b/src/AbstractAlgebra.jl @@ -28,7 +28,10 @@ const import_exclude = [:import_exclude, :QQ, :ZZ, # imported here and in Generic.jl, and exported below. # They should not be imported/exported anywhere else. +import LinearAlgebra + import LinearAlgebra: det +import LinearAlgebra: dot import LinearAlgebra: hessenberg import LinearAlgebra: ishermitian import LinearAlgebra: issymmetric diff --git a/src/NCRings.jl b/src/NCRings.jl index d8f2953ec0..a95daf9f1e 100644 --- a/src/NCRings.jl +++ b/src/NCRings.jl @@ -290,3 +290,15 @@ Base.oftype(x::NCRingElem, y::Rational) = parent(x)(y) ############################################################################### Base.broadcastable(x::NCRingElem) = Ref(x) + +################################################################################ +# +# Dot +# +################################################################################ + +dot(x::NCRingElem, y::NCRingElem) = x * y + +dot(x::NCRingElem, y::Union{Integer, Rational, AbstractFloat}) = x * y + +dot(x::Union{Integer, Rational, AbstractFloat}, y::NCRingElem) = x * y diff --git a/src/NemoStuff.jl b/src/NemoStuff.jl index 8a4052fda0..b6cb93fd99 100644 --- a/src/NemoStuff.jl +++ b/src/NemoStuff.jl @@ -398,9 +398,6 @@ end Random.gentype(::Type{T}) where {T<:FinField} = elem_type(T) -import LinearAlgebra -LinearAlgebra.dot(a::NCRingElem, b::NCRingElem) = a * b - transpose!(A::MatrixElem) = transpose(A) function Base.div(f::PolyRingElem, g::PolyRingElem) diff --git a/src/PrettyPrinting.jl b/src/PrettyPrinting.jl index c4c98a6c96..c739462f89 100644 --- a/src/PrettyPrinting.jl +++ b/src/PrettyPrinting.jl @@ -1648,24 +1648,67 @@ end # ################################################################################ -# A non-compiletime preference -function allow_unicode(flag::Bool) - old_flag = is_unicode_allowed() - @set_preferences!("unicode" => flag) - return old_flag +const ALLOW_UNICODE_OVERRIDE_VALUE = Ref{Union{Bool,Nothing}}(nothing) + +@doc """ + allow_unicode(allowed::Bool; temporary::Bool=false) -> Bool + +Set whether unicode characters are allowed in pretty printing and returns the +previous value. +If `temporary` is `true`, then the change is only active for the current worker and session. +Otherwise, the change is permanently saved in the preferences. +A permanent change will always override a temporary change. + +This function may behave arbitrarily if called from within the scope of a +`with_unicode` do-block. +""" +function allow_unicode(allowed::Bool; temporary::Bool=false) + if temporary + old_allowed = is_unicode_allowed() + ALLOW_UNICODE_OVERRIDE_VALUE[] = allowed + return old_allowed + else + old_allowed = is_unicode_allowed() + @set_preferences!("unicode" => allowed) + ALLOW_UNICODE_OVERRIDE_VALUE[] = nothing + return old_allowed + end end +@doc """ + is_unicode_allowed() -> Bool + +Return whether unicode characters are allowed in pretty printing. +""" function is_unicode_allowed() - return @load_preference("unicode", default = false) + override = ALLOW_UNICODE_OVERRIDE_VALUE[] + !isnothing(override) && return override + return @load_preference("unicode", default = false)::Bool end -function with_unicode(f::Function) - old_allow_unicode = allow_unicode(true) - try - f() - finally - allow_unicode(old_allow_unicode) - end +@doc """ + with_unicode(f::Function, allowed::Bool=true) + +Temporarily set whether unicode characters are allowed in pretty printing +during the execution of `f`. +This is useful for e.g. running doctests independently on the user preference. + +`with_unicode` is expected to be called in the following way: +```julia +with_unicode([allowed]) do + # code that should be executed with unicode allowed/disallowed +end +``` +""" +function with_unicode(f::Function, allowed::Bool=true) + previous = ALLOW_UNICODE_OVERRIDE_VALUE[] + ALLOW_UNICODE_OVERRIDE_VALUE[] = allowed + try + f() + finally + @assert ALLOW_UNICODE_OVERRIDE_VALUE[] == allowed + ALLOW_UNICODE_OVERRIDE_VALUE[] = previous + end end ################################################################################ diff --git a/test/NCRings-test.jl b/test/NCRings-test.jl index 530443fc5b..5f77883996 100644 --- a/test/NCRings-test.jl +++ b/test/NCRings-test.jl @@ -56,3 +56,22 @@ end M = matrix_space(ZZ, 2, rand(3:9)) @test_throws DomainError powers(rand(M, 1:9), rand(1:9)) end + +@testset "dot" begin + dot = AbstractAlgebra.LinearAlgebra.dot + + Qx, x = QQ["x"] + @test dot([x, x^2], [1, 1]) == x + x^2 + @test dot([x, x^2], Rational{BigInt}[1, 1]) == x + x^2 + @test dot([1, 1], [x, x^2]) == x + x^2 + @test dot(Rational{BigInt}[1, 1], [x, x^2]) == x + x^2 + @test dot([x], [x^2]) == x^3 + + R = matrix_ring(QQ, 2) + x = R([1 2; 3 4]) + @test dot([x, x^2], [1, 1]) == x + x^2 + @test dot([x, x^2], Rational{BigInt}[1, 1]) == x + x^2 + @test dot([1, 1], [x, x^2]) == x + x^2 + @test dot(Rational{BigInt}[1, 1], [x, x^2]) == x + x^2 + @test dot([x], [x^2]) == x^3 +end