Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grh demo #1334

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions examples/RandInt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@


#from https://pages.cs.wisc.edu/~cs812-1/pfrn.pdf
# SIAM J. COMPUT.
# Vol. 17, No. 2, April 1988
#HOW TO GENERATE FACTORED RANDOM NUMBERS
#ERIC BACH

module RandFacInt
using Hecke
import Nemo

import Base.*

#uses rand(1:128)/128.0 as a uniform random real in (0,1) for comparisons

*(a::BigFloat, b::QQFieldElem) = a*BigFloat(b)

function Delta(N::ZZRingElem, e::Int, p::ZZRingElem)
#to only do the is_prime_power ONCE
q = p^e
return Base.log(p)/Base.log(N) * BigFloat((floor(N//q) - ceil(N//(2*q)) + 1)//N)
end

function is_pr_prime_power(q::ZZRingElem; proof::Bool = true)
e, p = Nemo._maximal_integer_root(q)
if proof
return is_prime(p), e, p
else
return is_probable_prime(p), e, p
end
end

function process_F(N::ZZRingElem; proof::Bool = true)
while true
j = rand(1:nbits(N)-1)
q =ZZ(2)<<j + rand(1:(ZZ(2)<<j)-1)

if q <= N
fl, e, p = is_pr_prime_power(q; proof)
if fl && rand(1:128) < 128*Delta(N, e, p)*BigFloat(2)^j
return e, p
end
end
end
end

function Base.log(x::Fac{ZZRingElem})
if length(x.fac) == 1
return Base.log(ZZ(1))
end
return sum(e*Base.log(p) for (p, e) = x.fac)
end

"""
rand_fac_int(N::ZZRingElem; proof::Bool = true)

Returns a uniform-random integer in (N/2..N) in factored form, based on
Bach's paper above.

"proof" controls if the primality of the factors is proven.
"""
function rand_fac_int(N::ZZRingElem; proof::Bool = true)
if N < 1
N = ZZ(1)
end
if N <= 10^6
return factor(rand(max(1, div(N, 2)):N))
end
while true
e, p = process_F(N; proof)
q = p^e
g = rand_fac_int(div(N, q); proof)
push!(g.fac, p=>e)
if rand(1:128) < Base.log(N//2)/Base.log(g)*128
return g
end
end
end

export rand_fac_int

end #module

using .RandFacInt
export rand_fac_int




3 changes: 0 additions & 3 deletions examples/strassen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import Hecke.Nemo: add!, mul!, zero!, sub!, solve_triu!, solve_tril!

const cutoff = 1500

#base case for the strassen
function Nemo.mul!(C::AbstractArray, A::AbstractArray, B::AbstractArray, add::Bool = false)
@assert size(C) == (2,2) && size(A) == (2,2) && size(B) == (2,2)
C[1,1] = A[1,1] * B[1,1] + A[1,2] * B[2,1]
Expand Down Expand Up @@ -196,6 +195,4 @@ function mul_strassen!(C::AbstractArray, A::AbstractArray, B::AbstractArray)
end
end

#see AbstractAlgebra.Strassen for an MatElem version

end # module
23 changes: 23 additions & 0 deletions src/Hecke.jl
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,29 @@ function print_cache(sym::Vector{Any})
end
end

use_GRH::Bool = false
function set_use_GRH(x::Bool)
global use_GRH
old = use_GRH
use_GRH = x
return old
end
function use_GRH()
global use_GRH
return use_GRH
end
GRH_stack = Set{Vector{Base.StackTraces.StackFrame}}()
function clear_GRH_usage()
global GRH_stack
empty!(GRH_stack)
end
function push_GRH!()
global use_GRH
global GRH_stack
use_GRH && push!(GRH_stack, stacktrace())
nothing
end

function print_cache()
print_cache(find_cache(Nemo))
print_cache(find_cache(Nemo.Generic))
Expand Down
19 changes: 13 additions & 6 deletions src/NumFieldOrd/NfOrd/Clgp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,11 @@ function class_group_current_h(c::ClassGrpCtx)
return c.h
end

function _class_unit_group(O::NfOrd; saturate_at_2::Bool = true, bound::Int = -1, method::Int = 3, large::Int = 1000, redo::Bool = false, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = true)
function _class_unit_group(O::NfOrd; saturate_at_2::Bool = true, bound::Int = -1, method::Int = 3, large::Int = 1000, redo::Bool = false, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = use_GRH())

@vprintln :UnitGroup 1 "Computing tentative class and unit group ..."

GRH && push_GRH!()
@v_do :UnitGroup 1 pushindent()
c = class_group_ctx(O, bound = bound, method = method, large = large, redo = redo, use_aut = use_aut)
@v_do :UnitGroup 1 popindent()
Expand Down Expand Up @@ -405,7 +406,7 @@ end
@doc raw"""
class_group(O::NfOrd; bound = -1,
redo = false,
GRH = true) -> GrpAbFinGen, Map
GRH = use_GRH()) -> GrpAbFinGen, Map

Returns a group $A$ and a map $f$ from $A$ to the set of ideals of $O$. The
inverse of the map is the projection onto the group of ideals modulo the group
Expand All @@ -422,8 +423,11 @@ Keyword arguments:
"""
function class_group(O::NfOrd; bound::Int = -1, method::Int = 3,
redo::Bool = false, unit_method::Int = 1,
large::Int = 1000, use_aut::Bool = is_automorphisms_known(nf(O)), GRH::Bool = true, do_lll::Bool = true,
large::Int = 1000, use_aut::Bool = is_automorphisms_known(nf(O)), GRH::Bool = use_GRH(), do_lll::Bool = true,
saturate_at_2::Bool = true)
GRH && push_GRH!() #record use of GRH ONLY if selected by preferences
#if the prefrences (set_use_GRH) are false and the user
#specifies true directly, no recording
if do_lll
OK = maximal_order(nf(O))
@assert OK.is_maximal == 1
Expand Down Expand Up @@ -453,8 +457,9 @@ A set of fundamental units of $\mathcal O$ can be
obtained via `[ f(U[1+i]) for i in 1:unit_group_rank(O) ]`.
`f(U[1])` will give a generator for the torsion subgroup.
"""
function unit_group(O::NfOrd; method::Int = 3, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = true)
function unit_group(O::NfOrd; method::Int = 3, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = use_GRH())
if is_maximal(O)
GRH && push_GRH!() #record use of GRH ONLY if selected by preferences
return _unit_group_maximal(O, method = method, unit_method = unit_method, use_aut = use_aut, GRH = GRH)
else
return unit_group_non_maximal(O)::Tuple{GrpAbFinGen, MapUnitGrp{NfAbsOrd{AnticNumberField,nf_elem}}}
Expand All @@ -470,7 +475,7 @@ obtained via `[ f(U[1+i]) for i in 1:unit_group_rank(O) ]`.
`f(U[1])` will give a generator for the torsion subgroup.
All elements will be returned in factored form.
"""
function unit_group_fac_elem(O::NfOrd; method::Int = 3, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = true, redo::Bool = false)
function unit_group_fac_elem(O::NfOrd; method::Int = 3, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = use_GRH(), redo::Bool = false)
if !is_maximal(O)
OK = maximal_order(nf(O))
UUU, mUUU = unit_group_fac_elem(OK)::Tuple{GrpAbFinGen, MapUnitGrp{FacElemMon{AnticNumberField}}}
Expand All @@ -485,6 +490,7 @@ function unit_group_fac_elem(O::NfOrd; method::Int = 3, unit_method::Int = 1, us
if c === nothing
O = lll(maximal_order(nf(O)))
end
GRH && push_GRH!() #record use of GRH ONLY if selected by preferences
_, UU, b = _class_unit_group(O, method = method, unit_method = unit_method, use_aut = use_aut, GRH = GRH, redo = redo)
@assert b==1
return unit_group_fac_elem(UU)::Tuple{GrpAbFinGen, MapUnitGrp{FacElemMon{AnticNumberField}}}
Expand All @@ -495,11 +501,12 @@ end

Computes the regulator of $O$, i.e. the discriminant of the unit lattice.
"""
function regulator(O::NfOrd; method::Int = 3, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = true)
function regulator(O::NfOrd; method::Int = 3, unit_method::Int = 1, use_aut::Bool = false, GRH::Bool = use_GRH())
c = get_attribute(O, :ClassGrpCtx)
if c === nothing
O = lll(maximal_order(nf(O)))
end
GRH && push_GRH!() #record use of GRH ONLY if selected by preferences
c, U, b = _class_unit_group(O, method = method, unit_method = unit_method, use_aut = use_aut, GRH = GRH)
@assert b == 1
unit_group_fac_elem(U)
Expand Down
Loading