Skip to content

Commit d8f890a

Browse files
committed
src/sage/geometry/cone.py: refactor Hilbert_basis()
Some refactorings to the implementation of Hilbert_basis(): * Construct a cone L from our linear_subspace() so that "y in L" works as intended (currently we try to coerce y into a vector space in a try/except block). This is not any faster, but it makes the code easier to read. * Remove the irreducibles from "gens" as we construct it. * Negate a condition in a loop to avoid bailing out with "continue" as part of the normal control flow. * Use a boolean indicator to check if the list of irreducibles was modified, rather than recomputing its length.
1 parent 931cc5e commit d8f890a

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

src/sage/geometry/cone.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4436,40 +4436,39 @@ def Hilbert_basis(self):
44364436
44374437
The primal Normaliz algorithm, see [Normaliz]_.
44384438
"""
4439-
if self.is_strictly_convex():
44404439

4441-
def not_in_linear_subspace(x):
4442-
return True
4440+
if self.is_strictly_convex():
4441+
# Used in lieu of our linear_subspace() for containment
4442+
# testing. None of the points we test can be zero, so
4443+
# checking the empty tuple is equivalent to checking a
4444+
# trivial subspace, and the empty tuple is faster.
4445+
L = ()
44434446
else:
4444-
linear_subspace = self.linear_subspace()
4445-
4446-
def not_in_linear_subspace(x):
4447-
# "x in linear_subspace" does not work, due to absence
4448-
# of coercion maps as of Github issue #10513.
4449-
try:
4450-
linear_subspace(x)
4451-
return False
4452-
except (TypeError, ValueError):
4453-
return True
4447+
# Our linear_subspace(), but as a cone, so that
4448+
# containment testing using "in" works properly.
4449+
L = Cone( (c*r for c in (1,-1) for r in self.lines()),
4450+
self.lattice() )
44544451

44554452
irreducible = list(self.rays()) # these are irreducible for sure
4456-
gens = list(self.semigroup_generators())
4457-
for x in irreducible:
4458-
try:
4459-
gens.remove(x)
4460-
except ValueError:
4461-
pass
4453+
irr_modified = False # have we appended to "irreducible"?
4454+
gens = [ x for x in self.semigroup_generators()
4455+
if x not in irreducible ]
44624456

4457+
from itertools import chain
44634458
while gens:
44644459
x = gens.pop()
4465-
if any(not_in_linear_subspace(y) and x-y in self
4466-
for y in irreducible+gens):
4467-
continue
4468-
irreducible.append(x)
4469-
if len(irreducible) == self.nrays():
4470-
return self.rays()
4471-
else:
4460+
if all( (y in L) or (x-y not in self)
4461+
for y in chain(irreducible,gens) ):
4462+
irreducible.append(x)
4463+
irr_modified = True
4464+
4465+
if irr_modified:
44724466
return PointCollection(irreducible, self.lattice())
4467+
else:
4468+
# Avoid the PointCollection overhead if nothing was
4469+
# added to the irreducible list beyond self.rays().
4470+
return self.rays()
4471+
44734472

44744473
def Hilbert_coefficients(self, point, solver=None, verbose=0,
44754474
*, integrality_tolerance=1e-3):

0 commit comments

Comments
 (0)