CoCalc Public Filesnemo-zmod-division.ipynb
Author: Samuel LeliÃ¨vre
Views : 103
Description: Try dividing 2 by 4 or 5 in Zmod(6) in Nemo
Compute Environment: Ubuntu 18.04 (Deprecated)

# 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 [ ]: