Nemo fmpq rationals

Hi everybody,
I’m making some experiments with Nemo package.
The ZZ (fmtz) representation of integers is perfect.
QQ (fmtq) seems quite good too, but …
I have some overflow problem.
QQ identifies with Rational{BigInt} naturally via a constructor. Operations leading to eventual overflow are managed correctly. So I can compute the inverse of fact(100).
The same way I can compute and print fact(100) in fmtz.
Now i would like to access any fmtq object numerator and denominator. So the denominator of inv_fact(100) should be the fmtz fact(100).
Actually it’s not the case. the num and den member functions called on an object of type fmtq transform to Int64 and create an error ???
I checked all the available documentation and although there are a lot of documented functions I couldn’t find any mean to access the numerator and denominator of a fmtq as fmtz objects.
Can anybody help ?
Thank you !

#http://nemocas.github.io/Nemo.jl/latest/fraction.html
using Nemo
function test_construct()
    f1=QQ(2,3)
    println(f1)
    println(typeof(f1))
    #fmpq s'identifie à Rational{fmpz}
    f2=ZZ(2)//ZZ(3)
    println(typeof(f2))
    f3=big(2)//3
    println(f3)
    println(typeof(f3))
    #conversion de Rational{BigInt} (type julia) vers fmpq
    f4=QQ(f3)
    println(f4)
    println(typeof(f4))
end

function inv_fact(n)
    R=QQ(1,1)
    for i in 1:n
        R*=QQ(1,i) #produit ds fmpq
    end
    return R
end

#test gestion débordement
function test_deb(n)
    S=QQ(0,1)
    for i in 0:n
        S+=inv_fact(i) #somme dans fmpq
    end
    return S
end

function tests()
    println("Constructions de rationnnels de fmpq")
    test_construct()
    println("------------------------------")
    println("Test débordement")
    IF100=inv_fact(100)
    println(IF100)
    println(typeof(IF100))
    println(IF100.den)#error converts to Int64 and shows inexact result 
    println(test_deb(20))
    println("------------------------------")
end

tests()

To save some time here’s another version of tests with annotations of printed results :

function tests()
    println("Constructions de rationnnels de fmpq")
    test_construct()
    println("------------------------------")
    println("Test débordement")
    IF100=inv_fact(100)
    @show IF100 
    #above instruction shows expected result 
    #=
    IF100 =                   1//93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
    =#
    println(typeof(IF100)) #correct fmpq 
    println(fieldnames(typeof(IF100))) #gives (:num, :den)
    println(IF100.num) #correct 1 !
    println(typeof(IF100.den)) #gives Int64 (wrong) should be fmpz or BigInt
    println(IF100.den)#error shows inexact result 4611686018440537788
    println(test_deb(20))
    println("------------------------------")
end

Again to save some time to people. the problem seems to come from access to data members den and num of fmpq structures.
Juia works very well with Rational{BigInt} objects.
Conversion apparently works as ‘show’ proves’.
But after this impossible to access data members using dot notation.
Can be a real problem when working with p-norms for example.

using Nemo

function inv_fact(n)
    R=big(1)//1
    for i in 1:n
        R*=1//i #produit ds fmpq
    end
    return R
end

IF100=inv_fact(100)
println(IF100) #OK
println(typeof(IF100)) #OK
println(IF100.den) #OK
IF100=QQ(IF100)
@show IF100 #OK
println(IF100.den) #WRONG !

For objects of type fmpq, numerator and denominator are accessed via the functions numerator and denominator. Accessing the internal fields is not encouraged and not part of the interface. (These are the same functions used to access the numerator and denominator of Rational).

2 Likes

Thank you thofma for your quick and accurate answer.
It works !
I consider this discussion as closed.
Regards.
Gilles