Sharednemo-zmod-division.ipynbOpen in CoCalc
Author: Samuel Lelièvre
Views : 6
Description: Try dividing 2 by 4 or 5 in Zmod(6) in Nemo

Division in the ring ZZ/6 in Julia

Following the 2018-05-01 thread on sage-devel about the case of SageMath, we explore the case of Julia and Nemo, a computer algebra package running in Julia.

The exploration is done in a project on CoCalc. It turns out Julia and Nemo are installed system-wide on CoCalc.

As Bill Hart recalls us in the sage-devel thread mentioned above

In Julia and Nemo, the slash operator is floating point division. For example, 1/2 is 0.5 not a half. For division in a ring, you want divexact (there is also a separate operator, div, for Euclidean division).

At the moment, the code in Nemo for this is actually incorrect, so it only gives you an answer in one of the two examples in this thread and an exception in the other case. It's not a difficult fix. It should be in the next version of Nemo.

In AbstractAlgebra (pure Julia, no Flint), we get:

julia> using AbstractAlgebra

Welcome to AbstractAlgebra version 0.0.6

AbstractAlgebra comes with absolutely no warranty whatsoever

julia> R = ResidueRing(ZZ, 6)
Residue ring of Integers modulo 6

julia> a = R(5)
5

julia> b = R(4)
4

julia> c = a*b
2

julia> divexact(c, a)
4

julia> divexact(c, b)
2
In [1]:
using AbstractAlgebra
WARNING: Compat.UTF8String is deprecated, use String instead. likely near /ext/julia/julia/share/julia/site/v0.6/IJulia/src/kernel.jl:31 WARNING: Compat.UTF8String is deprecated, use String instead. likely near /ext/julia/julia/share/julia/site/v0.6/IJulia/src/kernel.jl:31 WARNING: Compat.UTF8String is deprecated, use String instead. likely near /ext/julia/julia/share/julia/site/v0.6/IJulia/src/kernel.jl:31 WARNING: Compat.UTF8String is deprecated, use String instead. likely near /ext/julia/julia/share/julia/site/v0.6/IJulia/src/kernel.jl:31 WARNING: Compat.UTF8String is deprecated, use String instead. likely near /ext/julia/julia/share/julia/site/v0.6/IJulia/src/kernel.jl:31
ArgumentError: Module AbstractAlgebra not found in current path. Run `Pkg.add("AbstractAlgebra")` to install the AbstractAlgebra package. Stacktrace: [1] _require(::Symbol) at ./loading.jl:435 [2] require(::Symbol) at ./loading.jl:405 [3] include_string(::String, ::String) at ./loading.jl:522
In [2]:
Pkg.add("AbstractAlgebra")
INFO: Initializing package repository /home/user/.julia/v0.6 INFO: Cloning METADATA from https://github.com/JuliaLang/METADATA.jl INFO: Cloning cache of AbstractAlgebra from https://github.com/Nemocas/AbstractAlgebra.jl.git INFO: Installing AbstractAlgebra v0.0.6 INFO: Package database updated
In [3]:
using AbstractAlgebra
INFO: Precompiling module AbstractAlgebra.
Welcome to AbstractAlgebra version 0.0.6 AbstractAlgebra comes with absolutely no warranty whatsoever
In [4]:
R = ResidueRing(ZZ, 6)
Residue ring of Integers modulo 6
In [5]:
a = R(5)
5
In [6]:
b = R(4)
4
In [7]:
c = a * b
2
In [8]:
c / a
MethodError: no method matching /(::AbstractAlgebra.Generic.Res{BigInt}, ::AbstractAlgebra.Generic.Res{BigInt}) Stacktrace: [1] include_string(::String, ::String) at ./loading.jl:522
In [9]:
c / b
MethodError: no method matching /(::AbstractAlgebra.Generic.Res{BigInt}, ::AbstractAlgebra.Generic.Res{BigInt}) Stacktrace: [1] include_string(::String, ::String) at ./loading.jl:522
In [10]:
divexact(c, a)
4
In [11]:
divexact(c, b)
2

Load Nemo, define two elements of ZZ/6 and their product

In [12]:
using Nemo
Welcome to Nemo version 0.7.3 Nemo comes with absolutely no warranty whatsoever
WARNING: Method definition gcd(Base.Rational{T<:Integer}, Base.Rational{T<:Integer}) in module AbstractAlgebra at /home/user/.julia/v0.6/AbstractAlgebra/src/julia/Rational.jl:110 overwritten in module Nemo at /ext/julia/julia-0.6.2/share/julia/site/v0.6/Nemo/src/julia/Rational.jl:103. WARNING: Method definition gcd(T<:AbstractFloat, T<:AbstractFloat) in module AbstractAlgebra at /home/user/.julia/v0.6/AbstractAlgebra/src/julia/Float.jl:102 overwritten in module Nemo at /ext/julia/julia-0.6.2/share/julia/site/v0.6/Nemo/src/julia/Float.jl:94. WARNING: Method definition parent(T<:Integer) in module AbstractAlgebra at /home/user/.julia/v0.6/AbstractAlgebra/src/julia/Integer.jl:17 overwritten in module Nemo at /ext/julia/julia-0.6.2/share/julia/site/v0.6/Nemo/src/julia/Integer.jl:17. WARNING: Method definition parent(Base.Rational{T<:Integer}) in module AbstractAlgebra at /home/user/.julia/v0.6/AbstractAlgebra/src/julia/Rational.jl:17 overwritten in module Nemo at /ext/julia/julia-0.6.2/share/julia/site/v0.6/Nemo/src/julia/Rational.jl:17. WARNING: Method definition parent(T<:AbstractFloat) in module AbstractAlgebra at /home/user/.julia/v0.6/AbstractAlgebra/src/julia/Float.jl:17 overwritten in module Nemo at /ext/julia/julia-0.6.2/share/julia/site/v0.6/Nemo/src/julia/Float.jl:17. WARNING: using Nemo.divexact in module Main conflicts with an existing identifier. WARNING: using Nemo.ZZ in module Main conflicts with an existing identifier. WARNING: using Nemo.ResidueRing in module Main conflicts with an existing identifier.
In [13]:
R = ResidueRing(ZZ, 6)
MethodError: Cannot `convert` an object of type Nemo.Integers{BigInt} to an object of type AbstractAlgebra.Ring This may have arisen from a call to the constructor AbstractAlgebra.Ring(...), since type constructors fall back to convert methods. Stacktrace: [1] AbstractAlgebra.Generic.ResRing{BigInt}(::BigInt, ::Bool) at /home/user/.julia/v0.6/AbstractAlgebra/src/generic/GenericTypes.jl:292 [2] #ResidueRing#36(::Bool, ::Function, ::AbstractAlgebra.Integers{BigInt}, ::Int64) at /home/user/.julia/v0.6/AbstractAlgebra/src/generic/Residue.jl:557 [3] (::AbstractAlgebra.Generic.#kw##ResidueRing)(::Array{Any,1}, ::AbstractAlgebra.Generic.#ResidueRing, ::AbstractAlgebra.Integers{BigInt}, ::Int64) at ./<missing>:0 [4] ResidueRing(::AbstractAlgebra.Integers{BigInt}, ::Int64) at /home/user/.julia/v0.6/AbstractAlgebra/src/AbstractAlgebra.jl:306 [5] include_string(::String, ::String) at ./loading.jl:522
In [14]:
a = R(5)
5
In [15]:
b = R(4)
4
In [16]:
c = a * b
2

Try dividing naively with /

In [17]:
c / a
MethodError: no method matching /(::AbstractAlgebra.Generic.Res{BigInt}, ::AbstractAlgebra.Generic.Res{BigInt}) Stacktrace: [1] include_string(::String, ::String) at ./loading.jl:522
In [18]:
c / b
MethodError: no method matching /(::AbstractAlgebra.Generic.Res{BigInt}, ::AbstractAlgebra.Generic.Res{BigInt}) Stacktrace: [1] include_string(::String, ::String) at ./loading.jl:522

What went wrong

As Bill Hart recalls us in the sage-devel thread mentioned above

In Julia and Nemo, the slash operator is floating point division. For example, 1/2 is 0.5 not a half. For division in a ring, you want divexact (there is also a separate operator, div, for Euclidean division).

At the moment, the code in Nemo for this is actually incorrect, so it only gives you an answer in one of the two examples in this thread and an exception in the other case. It's not a difficult fix. It should be in the next version of Nemo.

In AbstractAlgebra (pure Julia, no Flint), we get:

julia> using AbstractAlgebra

Welcome to AbstractAlgebra version 0.0.6

AbstractAlgebra comes with absolutely no warranty whatsoever

julia> R = ResidueRing(ZZ, 6)
Residue ring of Integers modulo 6

julia> a = R(5)
5

julia> b = R(4)
4

julia> c = a*b
2

julia> divexact(c, a)
4

julia> divexact(c, b)
2

So let's try again.

Using divexact to perform division in ZZ/6

In [19]:
divexact(c, a)
4
In [20]:
divexact(c, b)
2
In [ ]: