Skip to content

Commit

Permalink
Merge pull request #94 from fplll/stats
Browse files Browse the repository at this point in the history
Generate more statistics
  • Loading branch information
malb committed Aug 4, 2017
2 parents 3832ec1 + fa46d29 commit f696929
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/fpylll/algorithms/bkz.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from fpylll import Enumeration
from fpylll import EnumerationError
from fpylll.util import adjust_radius_to_gh_bound
from fpylll.algorithms.bkz_stats import BKZTreeTracer, dummy_tracer
from fpylll.tools.bkz_stats import BKZTreeTracer, dummy_tracer


class BKZReduction:
Expand Down
2 changes: 1 addition & 1 deletion src/fpylll/algorithms/bkz2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from random import randint
from fpylll import BKZ, Enumeration, EnumerationError
from fpylll.algorithms.bkz import BKZReduction as BKZBase
from fpylll.algorithms.bkz_stats import dummy_tracer
from fpylll.tools.bkz_stats import dummy_tracer
from fpylll.util import gaussian_heuristic


Expand Down
2 changes: 1 addition & 1 deletion src/fpylll/algorithms/pbkz.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from fpylll import BKZ, Enumeration, EnumerationError
from fpylll.algorithms.bkz import BKZReduction as BKZ1
from fpylll.algorithms.bkz2 import BKZReduction as BKZ2
from fpylll.algorithms.bkz_stats import BKZTreeTracer, dummy_tracer
from fpylll.tools.bkz_stats import BKZTreeTracer, dummy_tracer
from fpylll.util import adjust_radius_to_gh_bound


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import copy
from collections import OrderedDict
from math import log
from fpylll.tools.quality import basis_quality


def pretty_dict(d, keyword_width=None, round_bound=9999):
Expand Down Expand Up @@ -730,8 +731,12 @@ def exit(self, **kwds):
pass

if label[0] == "tour":
node.data["r_0"] = Statistic(self.instance.M.get_r(0, 0), repr="min")
node.data["/"] = Statistic(self.instance.M.get_current_slope(0, self.instance.A.nrows), repr="min")
data = basis_quality(self.instance.M)
for k, v in data.items():
if k == "/":
node.data[k] = Statistic(v, repr="max")
else:
node.data[k] = Statistic(v, repr="min")

if self.verbosity and label[0] == "tour":
report = OrderedDict()
Expand All @@ -746,14 +751,14 @@ def exit(self, **kwds):
report["svp"] = node.find("enumeration", True)["cputime"]
except KeyError:
pass
report["#enum"] = node.sum("#enum")
report["lll"] = node.sum("cputime", label="lll")
try:
report["pruner"] = node.find("pruner", True)["cputime"]
except KeyError:
pass
report["r_0"] = node["r_0"]
report["/"] = node["/"]
report["#enum"] = node.sum("#enum")

print(pretty_dict(report))

Expand Down
65 changes: 65 additions & 0 deletions src/fpylll/tools/quality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
"""
"""

from math import log, exp
from collections import OrderedDict
from fpylll.util import gaussian_heuristic


def basis_quality(M):
r"""
Return a dictionary with various expressions of quality of the basis corresponding to ``M``.
Let `|b_i^*|` be the norm of the `i`-th Gram-Schmidt vector. Let `Λ` be the lattice spanned by
the basis of dimension `d`.
- ``r_0`` - `|b_0|^2`
- ``\`` - the slope of `\log(|b_i^*|)`
- ``rhf`` - the root-Hermite factor `|b_0|/\Vol(Λ)^{1/d}` also written as `\delta_0`
- ``hv/hv`` - the dth-root of the fraction of the first and second half-volumes, i.e. the
dth-root of `∏_{i=0}^{d/2-1} |b_i|/∏_{i=d/2}^{d-1} |b_i|`. If `d` is odd, the length
`|b_{d//2}|` is ignored.
- ``r_0/gh`` - `|b_0|/GH` where `GH = Γ(d/2+1)^{1/d}/π^{1/2} ⋅ \Vol(Λ)^{1/d}` is the Gaussian
Heuristic for the shortest vector.
:param M: A MatGSO object.
:example:
>>> from fpylll import IntegerMatrix, GSO, LLL, set_random_seed
>>> set_random_seed(1337)
>>> A = IntegerMatrix.random(100, "qary", bits=30, k=50)
>>> _ = LLL.reduction(A)
>>> M = GSO.Mat(A); _ = M.update_gso()
>>> from fpylll.tools.quality import basis_quality
>>> from fpylll.tools.bkz_stats import pretty_dict
>>> str(pretty_dict(basis_quality(M)))
'{"r_0": 2^34.0, "r_0/gh": 9.389811, "rhf": 1.020530, "/": -0.08550, "hv/hv": 2.940943}'
"""

d = M.d

ret = OrderedDict()

r = [M.get_r(i, i) for i in range(d)]

log_volume = sum(log(r_)/2 for r_ in r)

lhs = sum(log(r_)/2 for r_ in r[:d//2])
rhs = sum(log(r_)/2 for r_ in r[d//2 + (d%2):])

ret["r_0"] = r[0]
ret["r_0/gh"] = r[0]/gaussian_heuristic(r)
ret["rhf"] = exp((log(r[0])/2.0 - log_volume/d)/d)
ret['/'] = M.get_current_slope(0, d)
ret["hv/hv"] = exp((lhs - rhs)/d)

return ret
2 changes: 1 addition & 1 deletion tests/test_bkz_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from fpylll.algorithms.simple_dbkz import DBKZReduction as SimpleDualBKZ
from fpylll.algorithms.bkz import BKZReduction as BKZ
from fpylll.algorithms.bkz2 import BKZReduction as BKZ2
from fpylll.algorithms.bkz_stats import BKZTreeTracer
from fpylll.tools.bkz_stats import BKZTreeTracer

from fpylll import BKZ as fplll_bkz
from fpylll.util import set_random_seed
Expand Down

0 comments on commit f696929

Please sign in to comment.