From 764c2e6c60ca5b9a2b24e5120d8bc8bddf6012ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 11 Apr 2024 18:27:46 +0200 Subject: [PATCH 1/7] Adapt QQBar documentation --- docs/src/algebraic.md | 24 ++++++------------------ docs/src/exact.md | 2 +- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/docs/src/algebraic.md b/docs/src/algebraic.md index 627f43826..f6e56de60 100644 --- a/docs/src/algebraic.md +++ b/docs/src/algebraic.md @@ -10,23 +10,12 @@ end Nemo allows working with exact real and complex algebraic numbers. The default algebraic number type in Nemo is provided by Calcium. The -associated field of algebraic numbers is represented by the constant -parent object called `CalciumQQBar`. +associated field of algebraic numbers can be constructed using +`QQBar = algebraic_closure(QQ)`. -For convenience we define - -``` -QQBar = CalciumQQBar -``` - -so that algebraic numbers can be constructed using `QQBar` instead of -`CalciumQQBar`. Note that this is the name of a specific parent object, -not the name of its type. - - - Library | Element type | Parent type -----------------|---------------|-------------------- -Calcium | `QQBarFieldElem` | `QQBarField` + Library | Element type | Parent type +----------------|------------------|-------------------- +Calcium | `QQBarFieldElem` | `QQBarField` **Important note on performance** @@ -38,8 +27,7 @@ For fast calculation in $\overline{\mathbb{Q}}$, `CalciumField` should typically be used instead (see the section on *Exact real and complex numbers*). Alternatively, to compute in a fixed subfield of $\overline{\mathbb{Q}}$, -you may fix a generator $a$ and construct an -Antic number field to represent $\mathbb{Q}(a)$. +you may fix a generator $a$ and construct a number field to represent $\mathbb{Q}(a)$. ## Algebraic number functionality diff --git a/docs/src/exact.md b/docs/src/exact.md index 66e4c5ce9..b37b4ef59 100644 --- a/docs/src/exact.md +++ b/docs/src/exact.md @@ -151,7 +151,7 @@ x^4 + -10*x^2 + 1 ## Conversions and numerical evaluation Calcium numbers can created from integers (`ZZ`), rationals (`QQ`) -and algebraic numbers (`QQbar`), and through the application of +and algebraic numbers (`algebraic_closure(QQ)`), and through the application of arithmetic operations and transcendental functions. Calcium numbers can be converted to integers, rational and algebraic fields From 61e86555e83cea73efeac8269948833ae5452fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 15 May 2024 15:48:28 +0200 Subject: [PATCH 2/7] Prepare for not exporting `QQBar` and `CalciumQQBar` --- docs/src/algebraic.md | 20 ++--- docs/src/exact.md | 2 +- src/Exports.jl | 4 +- src/Nemo.jl | 2 +- src/calcium/CalciumTypes.jl | 2 +- src/calcium/qqbar.jl | 18 ++-- test/calcium/ca-test.jl | 1 + test/calcium/qqbar-test.jl | 161 ++++++++++++++++++------------------ 8 files changed, 108 insertions(+), 102 deletions(-) diff --git a/docs/src/algebraic.md b/docs/src/algebraic.md index f6e56de60..d9a31f35e 100644 --- a/docs/src/algebraic.md +++ b/docs/src/algebraic.md @@ -46,7 +46,7 @@ Methods to construct algebraic numbers include: Arithmetic: -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> ZZRingElem(QQBar(3)) 3 @@ -59,7 +59,7 @@ Root 0.500000 + 0.866025*im of x^2 - x + 1 Solving the quintic equation: -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> R, x = polynomial_ring(QQ, "x") (Univariate polynomial ring in x over QQ, x) @@ -77,7 +77,7 @@ true Computing exact eigenvalues of a matrix: -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> eigenvalues(QQBar, ZZ[1 1 0; 0 1 1; 1 0 1]) 3-element Vector{QQBarFieldElem}: Root 2.00000 of x - 2 @@ -105,7 +105,7 @@ Algebraic numbers can be evaluated numerically to arbitrary precision by converting to real or complex Arb fields: -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> RR = ArbField(64); RR(sqrt(QQBar(2))) [1.414213562373095049 +/- 3.45e-19] @@ -120,7 +120,7 @@ julia> CC = AcbField(32); CC(QQBar(-1) ^ (QQBar(1) // 4)) Retrieving the minimal polynomial and algebraic conjugates of a given algebraic number: -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> minpoly(polynomial_ring(ZZ, "x")[1], QQBar(1+2im)) x^2 - 2*x + 5 @@ -153,7 +153,7 @@ height_bits(x::QQBarFieldElem) **Examples** -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> real(sqrt(QQBar(1im))) Root 0.707107 of 2x^2 - 1 @@ -211,7 +211,7 @@ first. **Examples** -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> 1 < sqrt(QQBar(2)) < QQBar(3)//2 true @@ -248,7 +248,7 @@ is_less_root_order(a::QQBarFieldElem, b::QQBarFieldElem) **Examples** -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> root(QQBar(2), 5) Root 1.14870 of x^5 - 2 @@ -303,7 +303,7 @@ atanpi(a::QQBarFieldElem) An algebraic number can be recovered from a numerical value: -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> RR = RealField(); guess(QQBar, RR("1.41421356 +/- 1e-6"), 2) Root 1.41421 of x^2 - 2 ``` @@ -313,7 +313,7 @@ approximation, you should add an error estimate; otherwise, at best the only algebraic number that can be guessed is the binary floating-point number itself, at worst no guess is possible. -```jldoctest +```jldoctest; setup = :(QQBar = algebraic_closure(QQ)) julia> RR = RealField(); julia> x = RR(0.1) # note: 53-bit binary approximation of 1//10 without radius diff --git a/docs/src/exact.md b/docs/src/exact.md index b37b4ef59..b1bc90f1d 100644 --- a/docs/src/exact.md +++ b/docs/src/exact.md @@ -165,7 +165,7 @@ value because of evaluation limits. julia> QQ(C(1)) 1 -julia> QQBar(sqrt(C(2)) // 2) +julia> algebraic_closure(QQ)(sqrt(C(2)) // 2) Root 0.707107 of 2x^2 - 1 julia> QQ(C(pi)) diff --git a/src/Exports.jl b/src/Exports.jl index 90f4f9413..895438b0c 100644 --- a/src/Exports.jl +++ b/src/Exports.jl @@ -63,7 +63,7 @@ export bits export bound_inf_norm export CalciumField export CalciumFieldElem -export CalciumQQBar +export CalciumQQBar # TODO: remove in next breaking release export canonical_unit export cdiv export cdivpow2 @@ -502,7 +502,7 @@ export QadicFieldElem export QQ export QQAbsPowerSeriesRing export QQAbsPowerSeriesRingElem -export QQBar +export QQBar # TODO: remove in next breaking release export QQBarField export QQBarFieldElem export QQField diff --git a/src/Nemo.jl b/src/Nemo.jl index 16cd0c1bf..8c30bba68 100644 --- a/src/Nemo.jl +++ b/src/Nemo.jl @@ -599,7 +599,7 @@ GaussianRationals() = FlintQQi ############################################################################### @doc qqbar_field_doc -const QQBar = CalciumQQBar +const CalciumQQBar = QQBar # TODO: remove in next breaking release ############################################################################### diff --git a/src/calcium/CalciumTypes.jl b/src/calcium/CalciumTypes.jl index 00d5a4d42..6fb64a393 100644 --- a/src/calcium/CalciumTypes.jl +++ b/src/calcium/CalciumTypes.jl @@ -86,7 +86,7 @@ Root 0.866025 of 4x^2 - 3 struct QQBarField <: Field end -const CalciumQQBar = QQBarField() +const QQBar = QQBarField() @doc qq_field_doc mutable struct QQBarFieldElem <: FieldElem diff --git a/src/calcium/qqbar.jl b/src/calcium/qqbar.jl index 62f957bac..c6a7836e4 100644 --- a/src/calcium/qqbar.jl +++ b/src/calcium/qqbar.jl @@ -10,7 +10,7 @@ # ############################################################################### -parent(a::QQBarFieldElem) = CalciumQQBar +parent(a::QQBarFieldElem) = QQBar parent_type(::Type{QQBarFieldElem}) = QQBarField @@ -178,9 +178,9 @@ zero(a::QQBarField) = a(0) one(a::QQBarField) = a(1) -zero(::Type{QQBarFieldElem}) = CalciumQQBar(0) +zero(::Type{QQBarFieldElem}) = QQBar(0) -one(::Type{QQBarFieldElem}) = CalciumQQBar(1) +one(::Type{QQBarFieldElem}) = QQBar(1) @doc raw""" degree(x::QQBarFieldElem) @@ -1176,7 +1176,9 @@ Throws if this value is transcendental. # Examples ```jldoctest -julia> x = sinpi(QQBar(1)//3) +julia> QQBar = algebraic_closure(QQ); + +julia> x = sinpi(QQBar(1//3)) Root 0.866025 of 4x^2 - 3 julia> sinpi(x) @@ -1202,7 +1204,9 @@ Throws if this value is transcendental. # Examples ```jldoctest -julia> x = cospi(QQBar(1)//6) +julia> QQBar = algebraic_closure(QQ); + +julia> x = cospi(QQBar(1//6)) Root 0.866025 of 4x^2 - 3 julia> cospi(x) @@ -1228,7 +1232,9 @@ Throws if either value is transcendental. # Examples ```jldoctest -julia> s, c = sincospi(QQBar(1)//3) +julia> QQBar = algebraic_closure(QQ); + +julia> s, c = sincospi(QQBar(1//3)) (Root 0.866025 of 4x^2 - 3, Root 0.500000 of 2x - 1) julia> sincospi(s) diff --git a/test/calcium/ca-test.jl b/test/calcium/ca-test.jl index e5db1dfca..fdb9a8033 100644 --- a/test/calcium/ca-test.jl +++ b/test/calcium/ca-test.jl @@ -237,6 +237,7 @@ end @testset "CalciumFieldElem.conversions" begin C = CalciumField() + QQBar = algebraic_closure(QQ) n = C(3) h = C(1) // 2 diff --git a/test/calcium/qqbar-test.jl b/test/calcium/qqbar-test.jl index 3e0bfb016..5748a0101 100644 --- a/test/calcium/qqbar-test.jl +++ b/test/calcium/qqbar-test.jl @@ -1,14 +1,14 @@ @testset "QQBarFieldElem.constructors" begin - R = CalciumQQBar + R = algebraic_closure(QQ) - @test R == QQBar + @test R == Nemo.QQBar @test elem_type(R) == QQBarFieldElem @test elem_type(QQBarField) == QQBarFieldElem @test parent_type(QQBarFieldElem) == QQBarField @test is_domain_type(QQBarFieldElem) == true - @test base_ring(CalciumQQBar) == Union{} - @test base_ring(QQBarFieldElem(3)) == Union{} + @test base_ring(R) == R + @test base_ring(QQBarFieldElem(3)) == R @test isa(R, QQBarField) @@ -41,38 +41,39 @@ end @testset "QQBarFieldElem.printing" begin - a = CalciumQQBar(1) + QQBar = algebraic_closure(QQ) + a = QQBar(1) @test string(a) == "Root 1.00000 of x - 1" @test string(parent(a)) == "Field of algebraic numbers" @test string(-(QQBarFieldElem(10) ^ 20)) == "Root -1.00000e+20 of x + 100000000000000000000" - @test string(root_of_unity(CalciumQQBar, 3)) == "Root -0.500000 + 0.866025*im of x^2 + x + 1" + @test string(root_of_unity(QQBar, 3)) == "Root -0.500000 + 0.866025*im of x^2 + x + 1" @test string(sqrt(QQBarFieldElem(-1)) // 3) == "Root 0.333333*im of 9x^2 + 1" end @testset "QQBarFieldElem.manipulation" begin - R = CalciumQQBar - - @test zero(R) == 0 - @test one(R) == 1 - @test isa(zero(R), QQBarFieldElem) - @test isa(one(R), QQBarFieldElem) - @test zero(R) == zero(QQBarFieldElem) - @test one(R) == one(QQBarFieldElem) - - @test iszero(R(0)) - @test isone(R(1)) - @test is_rational(R(1)) - @test isreal(R(1)) - @test degree(R(1)) == 1 - - u = sqrt(R(2)) - i = sqrt(R(-1)) + QQBar = algebraic_closure(QQ) + + @test zero(QQBar) == 0 + @test one(QQBar) == 1 + @test isa(zero(QQBar), QQBarFieldElem) + @test isa(one(QQBar), QQBarFieldElem) + @test zero(QQBar) == zero(QQBarFieldElem) + @test one(QQBar) == one(QQBarFieldElem) + + @test iszero(QQBar(0)) + @test isone(QQBar(1)) + @test is_rational(QQBar(1)) + @test isreal(QQBar(1)) + @test degree(QQBar(1)) == 1 - @test i == R(0+1im) - @test 3+4*i == R(3+4im) + u = sqrt(QQBar(2)) + i = sqrt(QQBar(-1)) + + @test i == QQBar(0+1im) + @test 3+4*i == QQBar(3+4im) @test canonical_unit(u) == u @test hash(u) != hash(i) @@ -118,9 +119,9 @@ end @test evaluate(x^2, u) == QQBarFieldElem(2) @test evaluate(y^2, u) == QQBarFieldElem(2) - @test root(QQBarFieldElem(-1), 3) == root_of_unity(R, 6) - @test root_of_unity(R, 4) == i - @test root_of_unity(R, 4, 3) == -i + @test root(QQBarFieldElem(-1), 3) == root_of_unity(QQBar, 6) + @test root_of_unity(QQBar, 4) == i + @test root_of_unity(QQBar, 4, 3) == -i @test sinpi(QQBarFieldElem(1)//6) == QQBarFieldElem(1)//2 @test cospi(QQBarFieldElem(1)//3) == QQBarFieldElem(1)//2 @@ -140,39 +141,39 @@ end @test_throws DomainError acospi(QQBarFieldElem(2)) @test_throws DomainError log_pi_i(QQBarFieldElem(2)) - @test_throws DivideError (R(1) // R(0)) - @test_throws DomainError (R(0) ^ R(-1)) - @test_throws DomainError (root(R(1), 0)) + @test_throws DivideError (QQBar(1) // QQBar(0)) + @test_throws DomainError (QQBar(0) ^ QQBar(-1)) + @test_throws DomainError (root(QQBar(1), 0)) @test_throws DomainError (u ^ u) - @test_throws DomainError (root_of_unity(R, 0)) - @test_throws DomainError (root_of_unity(R, 0, 1)) + @test_throws DomainError (root_of_unity(QQBar, 0)) + @test_throws DomainError (root_of_unity(QQBar, 0, 1)) @test is_root_of_unity(i) @test !is_root_of_unity(QQBarFieldElem(2)) @test root_of_unity_as_args(-i) == (4, 3) @test_throws DomainError root_of_unity_as_args(QQBarFieldElem(2)) - v = roots(CalciumQQBar, x^5-x-1) + v = roots(QQBar, x^5-x-1) @test v[1]^5 - v[1] - 1 == 0 - v = roots(CalciumQQBar, y^2+1) + v = roots(QQBar, y^2+1) @test v == [i, -i] - @test roots(CalciumQQBar, ZZx(0)) == [] - @test roots(CalciumQQBar, ZZx(1)) == [] - @test roots(CalciumQQBar, QQy(0)) == [] - @test roots(CalciumQQBar, QQy(1)) == [] - - @test eigenvalues(CalciumQQBar, zero(matrix_space(ZZ, 0, 0))) == [] - @test eigenvalues(CalciumQQBar, zero(matrix_space(QQ, 0, 0))) == [] - @test eigenvalues(CalciumQQBar, ZZ[1 1; 1 -1]) == [u, -u] - @test eigenvalues_with_multiplicities(CalciumQQBar, ZZ[1 1; 1 -1]) == [(u, 1), (-u, 1)] - @test eigenvalues(CalciumQQBar, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [u, -u] - @test eigenvalues_with_multiplicities(CalciumQQBar, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [(u, 2), (-u, 2)] - @test eigenvalues(CalciumQQBar, QQ[1 1; 1 -1]) == [u, -u] - @test eigenvalues_with_multiplicities(CalciumQQBar, QQ[1 1; 1 -1]) == [(u, 1), (-u, 1)] - @test eigenvalues(CalciumQQBar, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [u, -u] - @test eigenvalues_with_multiplicities(CalciumQQBar, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [(u, 2), (-u, 2)] + @test roots(QQBar, ZZx(0)) == [] + @test roots(QQBar, ZZx(1)) == [] + @test roots(QQBar, QQy(0)) == [] + @test roots(QQBar, QQy(1)) == [] + + @test eigenvalues(QQBar, zero(matrix_space(ZZ, 0, 0))) == [] + @test eigenvalues(QQBar, zero(matrix_space(QQ, 0, 0))) == [] + @test eigenvalues(QQBar, ZZ[1 1; 1 -1]) == [u, -u] + @test eigenvalues_with_multiplicities(QQBar, ZZ[1 1; 1 -1]) == [(u, 1), (-u, 1)] + @test eigenvalues(QQBar, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [u, -u] + @test eigenvalues_with_multiplicities(QQBar, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [(u, 2), (-u, 2)] + @test eigenvalues(QQBar, QQ[1 1; 1 -1]) == [u, -u] + @test eigenvalues_with_multiplicities(QQBar, QQ[1 1; 1 -1]) == [(u, 1), (-u, 1)] + @test eigenvalues(QQBar, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [u, -u] + @test eigenvalues_with_multiplicities(QQBar, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [(u, 2), (-u, 2)] @test conjugates(QQBarFieldElem(3)) == [QQBarFieldElem(3)] @test conjugates(u) == [u, -u] @@ -189,38 +190,38 @@ end @test_throws DomainError (RR(i)) v = sqrt(RR(2)) + sqrt(RR(3)) - @test guess(CalciumQQBar, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test guess(CalciumQQBar, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test_throws ErrorException guess(CalciumQQBar, v, 2) + @test guess(QQBar, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test guess(QQBar, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test_throws ErrorException guess(QQBar, v, 2) - @test guess(CalciumQQBar, CC(2+i), 2, 10) == 2+i + @test guess(QQBar, CC(2+i), 2, 10) == 2+i Rx, x = polynomial_ring(QQBar, "x") @test gcd(x^4 - 4*x^2 + 4, x^2 + sqrt(QQBar(18))*x + 4) == x + sqrt(QQBar(2)) end # floor, ceil, round - a = sqrt(R(2)) + a = sqrt(QQBar(2)) test_data = [(a, 1, 2, 1, 1, 2, 1), - (R(1), 1, 1, 1, 1, 1, 1), - (R(0), 0, 0, 0, 0, 0, 0), - (R(1//2), 0, 1, 1, 0, 1, 0), - (R(3//2), 1, 2, 2, 1, 2, 2), - (R(-1//2), -1, 0, -1, -1, 0, 0), - (sqrt(R(3)), 1, 2, 2, 1, 2, 2), + (QQBar(1), 1, 1, 1, 1, 1, 1), + (QQBar(0), 0, 0, 0, 0, 0, 0), + (QQBar(1//2), 0, 1, 1, 0, 1, 0), + (QQBar(3//2), 1, 2, 2, 1, 2, 2), + (QQBar(-1//2), -1, 0, -1, -1, 0, 0), + (sqrt(QQBar(3)), 1, 2, 2, 1, 2, 2), ] for (e, f, c, r, rd, ru, rn) in test_data - @test floor(e) == f && parent(floor(e)) === R + @test floor(e) == f && parent(floor(e)) === QQBar @test floor(ZZRingElem, e) == f && floor(ZZRingElem, e) isa ZZRingElem - @test ceil(e) == R(c) && parent(ceil(e)) === R + @test ceil(e) == QQBar(c) && parent(ceil(e)) === QQBar @test ceil(ZZRingElem, e) == c && ceil(ZZRingElem, e) isa ZZRingElem - @test round(e) == r && parent(round(e)) === R + @test round(e) == r && parent(round(e)) === QQBar @test round(ZZRingElem, e) == r && round(ZZRingElem, e) isa ZZRingElem - @test round(e, RoundDown) == rd && parent(round(e, RoundDown)) === R + @test round(e, RoundDown) == rd && parent(round(e, RoundDown)) === QQBar @test round(ZZRingElem, e, RoundDown) == rd && round(ZZRingElem, e, RoundDown) isa ZZRingElem - @test round(e, RoundUp) == ru && parent(round(e, RoundUp)) === R + @test round(e, RoundUp) == ru && parent(round(e, RoundUp)) === QQBar @test round(ZZRingElem, e, RoundUp) == ru && round(ZZRingElem, e, RoundUp) isa ZZRingElem - @test round(e, RoundNearest) == rn && parent(round(e, RoundNearest)) === R + @test round(e, RoundNearest) == rn && parent(round(e, RoundNearest)) === QQBar @test round(ZZRingElem, e, RoundNearest) == rn && round(ZZRingElem, e, RoundNearest) isa ZZRingElem end @@ -232,11 +233,11 @@ end @test_throws DomainError (RR(i)) v = sqrt(RR(2)) + sqrt(RR(3)) - @test guess(CalciumQQBar, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test guess(CalciumQQBar, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test_throws ErrorException guess(CalciumQQBar, v, 2) + @test guess(QQBar, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test guess(QQBar, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test_throws ErrorException guess(QQBar, v, 2) - @test guess(CalciumQQBar, CC(2+i), 2, 10) == 2+i + @test guess(QQBar, CC(2+i), 2, 10) == 2+i Rx, x = polynomial_ring(QQBar, "x") @test gcd(x^4 - 4*x^2 + 4, x^2 + sqrt(QQBar(18))*x + 4) == x + sqrt(QQBar(2)) @@ -244,8 +245,6 @@ end end @testset "QQBarFieldElem.adhoc_operations" begin - R = CalciumQQBar - @test QQBarFieldElem(2) + QQBarFieldElem(3) == 5 @test QQBarFieldElem(2) + 3 == 5 @test QQBarFieldElem(2) + ZZRingElem(3) == 5 @@ -297,7 +296,7 @@ end end @testset "QQBarFieldElem.comparison" begin - R = CalciumQQBar + R = algebraic_closure(QQ) u = R(3) // 2 i = sqrt(R(-1)) @@ -350,7 +349,7 @@ end @testset "QQBarFieldElem.inplace" begin - R = CalciumQQBar + R = algebraic_closure(QQ) x = R(7) zero!(x) @@ -374,25 +373,25 @@ end end @testset "QQBarFieldElem.rand" begin - R = CalciumQQBar + QQBar = algebraic_closure(QQ) for i=1:10 - x = rand(CalciumQQBar, degree=5, bits=5) + x = rand(QQBar, degree=5, bits=5) @test degree(x) <= 5 end for i=1:10 - x = rand(CalciumQQBar, degree=5, bits=5, randtype=:real) + x = rand(QQBar, degree=5, bits=5, randtype=:real) @test isreal(x) end for i=1:10 - x = rand(CalciumQQBar, degree=5, bits=5, randtype=:nonreal) + x = rand(QQBar, degree=5, bits=5, randtype=:nonreal) # todo: need to upgrade Calcium # @test !isreal(x) end - @test_throws ErrorException rand(CalciumQQBar, degree=2, bits=5, randtype=:gollum) + @test_throws ErrorException rand(QQBar, degree=2, bits=5, randtype=:gollum) end @@ -401,6 +400,6 @@ function test_elem(R::QQBarField) end @testset "QQBarFieldElem.conformance_tests" begin - test_Field_interface(CalciumQQBar) + test_Field_interface(algebraic_closure(QQ)) end From 71267052569f42c0a8e582d0bc9a32e48b56b40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 29 May 2024 12:15:59 +0200 Subject: [PATCH 3/7] Add note to doctestsetup --- docs/src/algebraic.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/algebraic.md b/docs/src/algebraic.md index d9a31f35e..27063c236 100644 --- a/docs/src/algebraic.md +++ b/docs/src/algebraic.md @@ -11,7 +11,8 @@ Nemo allows working with exact real and complex algebraic numbers. The default algebraic number type in Nemo is provided by Calcium. The associated field of algebraic numbers can be constructed using -`QQBar = algebraic_closure(QQ)`. +`QQBar = algebraic_closure(QQ)`. We will leave out this line from +all code blocks on this page for brevity. Library | Element type | Parent type ----------------|------------------|-------------------- From dd894a8c27a78804b07b03765c185a0f01a5f086 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 6 Jun 2024 22:38:08 +0200 Subject: [PATCH 4/7] Apply suggestions from code review --- src/calcium/qqbar.jl | 6 +++--- test/calcium/qqbar-test.jl | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/calcium/qqbar.jl b/src/calcium/qqbar.jl index c6a7836e4..ea017e72f 100644 --- a/src/calcium/qqbar.jl +++ b/src/calcium/qqbar.jl @@ -10,7 +10,7 @@ # ############################################################################### -parent(a::QQBarFieldElem) = QQBar +parent(a::QQBarFieldElem) = QQBarField() parent_type(::Type{QQBarFieldElem}) = QQBarField @@ -178,9 +178,9 @@ zero(a::QQBarField) = a(0) one(a::QQBarField) = a(1) -zero(::Type{QQBarFieldElem}) = QQBar(0) +zero(::Type{QQBarFieldElem}) = QQBarFieldElem(0) -one(::Type{QQBarFieldElem}) = QQBar(1) +one(::Type{QQBarFieldElem}) = QQBarFieldElem(1) @doc raw""" degree(x::QQBarFieldElem) diff --git a/test/calcium/qqbar-test.jl b/test/calcium/qqbar-test.jl index 5748a0101..d1306255c 100644 --- a/test/calcium/qqbar-test.jl +++ b/test/calcium/qqbar-test.jl @@ -1,8 +1,6 @@ @testset "QQBarFieldElem.constructors" begin R = algebraic_closure(QQ) - @test R == Nemo.QQBar - @test elem_type(R) == QQBarFieldElem @test elem_type(QQBarField) == QQBarFieldElem @test parent_type(QQBarFieldElem) == QQBarField From c80d76a58e5a454e8dd6e4503189ec0a444979ef Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 6 Jun 2024 22:48:38 +0200 Subject: [PATCH 5/7] straighten out some tests --- test/calcium/ca-test.jl | 8 +- test/calcium/qqbar-test.jl | 152 ++++++++++++++++++------------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/test/calcium/ca-test.jl b/test/calcium/ca-test.jl index fdb9a8033..b9f1a8946 100644 --- a/test/calcium/ca-test.jl +++ b/test/calcium/ca-test.jl @@ -237,7 +237,7 @@ end @testset "CalciumFieldElem.conversions" begin C = CalciumField() - QQBar = algebraic_closure(QQ) + R = algebraic_closure(QQ) n = C(3) h = C(1) // 2 @@ -249,9 +249,9 @@ end @test QQ(h) == QQFieldElem(1) // 2 @test_throws ErrorException ZZ(h) - @test CalciumQQBar(h) == QQBarFieldElem(1) // 2 - @test CalciumQQBar(c) == QQBarFieldElem(1+2im) - @test_throws ErrorException CalciumQQBar(t) + @test R(h) == QQBarFieldElem(1) // 2 + @test R(c) == QQBarFieldElem(1+2im) + @test_throws ErrorException R(t) RR = ArbField(64) CC = AcbField(64) diff --git a/test/calcium/qqbar-test.jl b/test/calcium/qqbar-test.jl index d1306255c..52778c7e0 100644 --- a/test/calcium/qqbar-test.jl +++ b/test/calcium/qqbar-test.jl @@ -5,8 +5,8 @@ @test elem_type(QQBarField) == QQBarFieldElem @test parent_type(QQBarFieldElem) == QQBarField @test is_domain_type(QQBarFieldElem) == true - @test base_ring(R) == R - @test base_ring(QQBarFieldElem(3)) == R + @test base_ring(R) == Union{} + @test base_ring(QQBarFieldElem(3)) == Union{} @test isa(R, QQBarField) @@ -39,39 +39,39 @@ end @testset "QQBarFieldElem.printing" begin - QQBar = algebraic_closure(QQ) - a = QQBar(1) + R = algebraic_closure(QQ) + a = R(1) @test string(a) == "Root 1.00000 of x - 1" @test string(parent(a)) == "Field of algebraic numbers" @test string(-(QQBarFieldElem(10) ^ 20)) == "Root -1.00000e+20 of x + 100000000000000000000" - @test string(root_of_unity(QQBar, 3)) == "Root -0.500000 + 0.866025*im of x^2 + x + 1" + @test string(root_of_unity(R, 3)) == "Root -0.500000 + 0.866025*im of x^2 + x + 1" @test string(sqrt(QQBarFieldElem(-1)) // 3) == "Root 0.333333*im of 9x^2 + 1" end @testset "QQBarFieldElem.manipulation" begin - QQBar = algebraic_closure(QQ) + R = algebraic_closure(QQ) - @test zero(QQBar) == 0 - @test one(QQBar) == 1 - @test isa(zero(QQBar), QQBarFieldElem) - @test isa(one(QQBar), QQBarFieldElem) - @test zero(QQBar) == zero(QQBarFieldElem) - @test one(QQBar) == one(QQBarFieldElem) + @test zero(R) == 0 + @test one(R) == 1 + @test isa(zero(R), QQBarFieldElem) + @test isa(one(R), QQBarFieldElem) + @test zero(R) == zero(QQBarFieldElem) + @test one(R) == one(QQBarFieldElem) - @test iszero(QQBar(0)) - @test isone(QQBar(1)) - @test is_rational(QQBar(1)) - @test isreal(QQBar(1)) - @test degree(QQBar(1)) == 1 + @test iszero(R(0)) + @test isone(R(1)) + @test is_rational(R(1)) + @test isreal(R(1)) + @test degree(R(1)) == 1 - u = sqrt(QQBar(2)) - i = sqrt(QQBar(-1)) + u = sqrt(R(2)) + i = sqrt(R(-1)) - @test i == QQBar(0+1im) - @test 3+4*i == QQBar(3+4im) + @test i == R(0+1im) + @test 3+4*i == R(3+4im) @test canonical_unit(u) == u @test hash(u) != hash(i) @@ -117,9 +117,9 @@ end @test evaluate(x^2, u) == QQBarFieldElem(2) @test evaluate(y^2, u) == QQBarFieldElem(2) - @test root(QQBarFieldElem(-1), 3) == root_of_unity(QQBar, 6) - @test root_of_unity(QQBar, 4) == i - @test root_of_unity(QQBar, 4, 3) == -i + @test root(QQBarFieldElem(-1), 3) == root_of_unity(R, 6) + @test root_of_unity(R, 4) == i + @test root_of_unity(R, 4, 3) == -i @test sinpi(QQBarFieldElem(1)//6) == QQBarFieldElem(1)//2 @test cospi(QQBarFieldElem(1)//3) == QQBarFieldElem(1)//2 @@ -139,39 +139,39 @@ end @test_throws DomainError acospi(QQBarFieldElem(2)) @test_throws DomainError log_pi_i(QQBarFieldElem(2)) - @test_throws DivideError (QQBar(1) // QQBar(0)) - @test_throws DomainError (QQBar(0) ^ QQBar(-1)) - @test_throws DomainError (root(QQBar(1), 0)) + @test_throws DivideError (R(1) // R(0)) + @test_throws DomainError (R(0) ^ R(-1)) + @test_throws DomainError (root(R(1), 0)) @test_throws DomainError (u ^ u) - @test_throws DomainError (root_of_unity(QQBar, 0)) - @test_throws DomainError (root_of_unity(QQBar, 0, 1)) + @test_throws DomainError (root_of_unity(R, 0)) + @test_throws DomainError (root_of_unity(R, 0, 1)) @test is_root_of_unity(i) @test !is_root_of_unity(QQBarFieldElem(2)) @test root_of_unity_as_args(-i) == (4, 3) @test_throws DomainError root_of_unity_as_args(QQBarFieldElem(2)) - v = roots(QQBar, x^5-x-1) + v = roots(R, x^5-x-1) @test v[1]^5 - v[1] - 1 == 0 - v = roots(QQBar, y^2+1) + v = roots(R, y^2+1) @test v == [i, -i] - @test roots(QQBar, ZZx(0)) == [] - @test roots(QQBar, ZZx(1)) == [] - @test roots(QQBar, QQy(0)) == [] - @test roots(QQBar, QQy(1)) == [] - - @test eigenvalues(QQBar, zero(matrix_space(ZZ, 0, 0))) == [] - @test eigenvalues(QQBar, zero(matrix_space(QQ, 0, 0))) == [] - @test eigenvalues(QQBar, ZZ[1 1; 1 -1]) == [u, -u] - @test eigenvalues_with_multiplicities(QQBar, ZZ[1 1; 1 -1]) == [(u, 1), (-u, 1)] - @test eigenvalues(QQBar, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [u, -u] - @test eigenvalues_with_multiplicities(QQBar, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [(u, 2), (-u, 2)] - @test eigenvalues(QQBar, QQ[1 1; 1 -1]) == [u, -u] - @test eigenvalues_with_multiplicities(QQBar, QQ[1 1; 1 -1]) == [(u, 1), (-u, 1)] - @test eigenvalues(QQBar, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [u, -u] - @test eigenvalues_with_multiplicities(QQBar, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [(u, 2), (-u, 2)] + @test roots(R, ZZx(0)) == [] + @test roots(R, ZZx(1)) == [] + @test roots(R, QQy(0)) == [] + @test roots(R, QQy(1)) == [] + + @test eigenvalues(R, zero(matrix_space(ZZ, 0, 0))) == [] + @test eigenvalues(R, zero(matrix_space(QQ, 0, 0))) == [] + @test eigenvalues(R, ZZ[1 1; 1 -1]) == [u, -u] + @test eigenvalues_with_multiplicities(R, ZZ[1 1; 1 -1]) == [(u, 1), (-u, 1)] + @test eigenvalues(R, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [u, -u] + @test eigenvalues_with_multiplicities(R, diagonal_matrix(ZZ[1 1; 1 -1], ZZ[1 1; 1 -1])) == [(u, 2), (-u, 2)] + @test eigenvalues(R, QQ[1 1; 1 -1]) == [u, -u] + @test eigenvalues_with_multiplicities(R, QQ[1 1; 1 -1]) == [(u, 1), (-u, 1)] + @test eigenvalues(R, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [u, -u] + @test eigenvalues_with_multiplicities(R, diagonal_matrix(QQ[1 1; 1 -1], QQ[1 1; 1 -1])) == [(u, 2), (-u, 2)] @test conjugates(QQBarFieldElem(3)) == [QQBarFieldElem(3)] @test conjugates(u) == [u, -u] @@ -188,38 +188,38 @@ end @test_throws DomainError (RR(i)) v = sqrt(RR(2)) + sqrt(RR(3)) - @test guess(QQBar, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test guess(QQBar, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test_throws ErrorException guess(QQBar, v, 2) + @test guess(R, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test guess(R, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test_throws ErrorException guess(R, v, 2) - @test guess(QQBar, CC(2+i), 2, 10) == 2+i + @test guess(R, CC(2+i), 2, 10) == 2+i - Rx, x = polynomial_ring(QQBar, "x") - @test gcd(x^4 - 4*x^2 + 4, x^2 + sqrt(QQBar(18))*x + 4) == x + sqrt(QQBar(2)) + Rx, x = polynomial_ring(R, "x") + @test gcd(x^4 - 4*x^2 + 4, x^2 + sqrt(R(18))*x + 4) == x + sqrt(R(2)) end # floor, ceil, round - a = sqrt(QQBar(2)) + a = sqrt(R(2)) test_data = [(a, 1, 2, 1, 1, 2, 1), - (QQBar(1), 1, 1, 1, 1, 1, 1), - (QQBar(0), 0, 0, 0, 0, 0, 0), - (QQBar(1//2), 0, 1, 1, 0, 1, 0), - (QQBar(3//2), 1, 2, 2, 1, 2, 2), - (QQBar(-1//2), -1, 0, -1, -1, 0, 0), - (sqrt(QQBar(3)), 1, 2, 2, 1, 2, 2), + (R(1), 1, 1, 1, 1, 1, 1), + (R(0), 0, 0, 0, 0, 0, 0), + (R(1//2), 0, 1, 1, 0, 1, 0), + (R(3//2), 1, 2, 2, 1, 2, 2), + (R(-1//2), -1, 0, -1, -1, 0, 0), + (sqrt(R(3)), 1, 2, 2, 1, 2, 2), ] for (e, f, c, r, rd, ru, rn) in test_data - @test floor(e) == f && parent(floor(e)) === QQBar + @test floor(e) == f && parent(floor(e)) === R @test floor(ZZRingElem, e) == f && floor(ZZRingElem, e) isa ZZRingElem - @test ceil(e) == QQBar(c) && parent(ceil(e)) === QQBar + @test ceil(e) == R(c) && parent(ceil(e)) === R @test ceil(ZZRingElem, e) == c && ceil(ZZRingElem, e) isa ZZRingElem - @test round(e) == r && parent(round(e)) === QQBar + @test round(e) == r && parent(round(e)) === R @test round(ZZRingElem, e) == r && round(ZZRingElem, e) isa ZZRingElem - @test round(e, RoundDown) == rd && parent(round(e, RoundDown)) === QQBar + @test round(e, RoundDown) == rd && parent(round(e, RoundDown)) === R @test round(ZZRingElem, e, RoundDown) == rd && round(ZZRingElem, e, RoundDown) isa ZZRingElem - @test round(e, RoundUp) == ru && parent(round(e, RoundUp)) === QQBar + @test round(e, RoundUp) == ru && parent(round(e, RoundUp)) === R @test round(ZZRingElem, e, RoundUp) == ru && round(ZZRingElem, e, RoundUp) isa ZZRingElem - @test round(e, RoundNearest) == rn && parent(round(e, RoundNearest)) === QQBar + @test round(e, RoundNearest) == rn && parent(round(e, RoundNearest)) === R @test round(ZZRingElem, e, RoundNearest) == rn && round(ZZRingElem, e, RoundNearest) isa ZZRingElem end @@ -231,14 +231,14 @@ end @test_throws DomainError (RR(i)) v = sqrt(RR(2)) + sqrt(RR(3)) - @test guess(QQBar, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test guess(QQBar, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) - @test_throws ErrorException guess(QQBar, v, 2) + @test guess(R, v, 4) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test guess(R, v, 4, 10) == sqrt(QQBarFieldElem(2)) + sqrt(QQBarFieldElem(3)) + @test_throws ErrorException guess(R, v, 2) - @test guess(QQBar, CC(2+i), 2, 10) == 2+i + @test guess(R, CC(2+i), 2, 10) == 2+i - Rx, x = polynomial_ring(QQBar, "x") - @test gcd(x^4 - 4*x^2 + 4, x^2 + sqrt(QQBar(18))*x + 4) == x + sqrt(QQBar(2)) + Rx, x = polynomial_ring(R, "x") + @test gcd(x^4 - 4*x^2 + 4, x^2 + sqrt(R(18))*x + 4) == x + sqrt(R(2)) end @@ -371,25 +371,25 @@ end end @testset "QQBarFieldElem.rand" begin - QQBar = algebraic_closure(QQ) + R = algebraic_closure(QQ) for i=1:10 - x = rand(QQBar, degree=5, bits=5) + x = rand(R, degree=5, bits=5) @test degree(x) <= 5 end for i=1:10 - x = rand(QQBar, degree=5, bits=5, randtype=:real) + x = rand(R, degree=5, bits=5, randtype=:real) @test isreal(x) end for i=1:10 - x = rand(QQBar, degree=5, bits=5, randtype=:nonreal) + x = rand(R, degree=5, bits=5, randtype=:nonreal) # todo: need to upgrade Calcium # @test !isreal(x) end - @test_throws ErrorException rand(QQBar, degree=2, bits=5, randtype=:gollum) + @test_throws ErrorException rand(R, degree=2, bits=5, randtype=:gollum) end From dc5f40dea588c3e7a68318d7e4d509bfede87546 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 6 Jun 2024 22:57:22 +0200 Subject: [PATCH 6/7] Remove two uses of QQBar --- src/calcium/ca.jl | 2 +- src/calcium/qqbar.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calcium/ca.jl b/src/calcium/ca.jl index e1510a21f..9706d4d53 100644 --- a/src/calcium/ca.jl +++ b/src/calcium/ca.jl @@ -1482,7 +1482,7 @@ end # todo: optimize function (C::CalciumField)(v::Complex{Int}) - return C(QQBar(v)) + return C(QQBarFieldElem(v)) end function (C::CalciumField)(x::Irrational) diff --git a/src/calcium/qqbar.jl b/src/calcium/qqbar.jl index ea017e72f..22ff12ced 100644 --- a/src/calcium/qqbar.jl +++ b/src/calcium/qqbar.jl @@ -1553,4 +1553,4 @@ julia> sqrt(K(2)) Root 1.41421 of x^2 - 2 ``` """ -algebraic_closure(::QQField) = QQBar +algebraic_closure(::QQField) = QQBarField() From 48dcd18dbec1d2fadba3f0304e230e5f0c71a6a2 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 6 Jun 2024 22:57:44 +0200 Subject: [PATCH 7/7] Move deprecated (Calcium)QQBar to src/Deprecations.jl --- src/Deprecations.jl | 6 ++++++ src/Exports.jl | 2 -- src/Nemo.jl | 10 ---------- src/calcium/CalciumTypes.jl | 2 -- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/Deprecations.jl b/src/Deprecations.jl index d03021664..fe97456f2 100644 --- a/src/Deprecations.jl +++ b/src/Deprecations.jl @@ -75,3 +75,9 @@ end is_power(x::IntegerUnion) = is_perfect_power_with_data(x) is_power(x::QQFieldElem) = is_perfect_power_with_data(x) is_power(x::Rational) = is_perfect_power_with_data(x) + +const QQBar = QQBarField() +export QQBar + +const CalciumQQBar = QQBarField() +export CalciumQQBar diff --git a/src/Exports.jl b/src/Exports.jl index 895438b0c..34ed781a2 100644 --- a/src/Exports.jl +++ b/src/Exports.jl @@ -63,7 +63,6 @@ export bits export bound_inf_norm export CalciumField export CalciumFieldElem -export CalciumQQBar # TODO: remove in next breaking release export canonical_unit export cdiv export cdivpow2 @@ -502,7 +501,6 @@ export QadicFieldElem export QQ export QQAbsPowerSeriesRing export QQAbsPowerSeriesRingElem -export QQBar # TODO: remove in next breaking release export QQBarField export QQBarFieldElem export QQField diff --git a/src/Nemo.jl b/src/Nemo.jl index 8c30bba68..28937c26a 100644 --- a/src/Nemo.jl +++ b/src/Nemo.jl @@ -592,16 +592,6 @@ const FlintQQ = QQ GaussianIntegers() = FlintZZi GaussianRationals() = FlintQQi -############################################################################### -# -# Set domain for QQBar to Calcium -# -############################################################################### - -@doc qqbar_field_doc -const CalciumQQBar = QQBar # TODO: remove in next breaking release - - ############################################################################### # # Some explicit type piracy against AbstractAlgebra diff --git a/src/calcium/CalciumTypes.jl b/src/calcium/CalciumTypes.jl index 6fb64a393..a3edae706 100644 --- a/src/calcium/CalciumTypes.jl +++ b/src/calcium/CalciumTypes.jl @@ -86,8 +86,6 @@ Root 0.866025 of 4x^2 - 3 struct QQBarField <: Field end -const QQBar = QQBarField() - @doc qq_field_doc mutable struct QQBarFieldElem <: FieldElem coeffs::Ptr{Nothing}