From 2f5fa896ec433e2d1c90134fd76ec6d7aed3aa92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 23 Sep 2025 09:53:56 +0200 Subject: [PATCH 1/5] better uniformity for polytope methods --- src/sage/categories/primer.py | 2 +- src/sage/combinat/quickref.py | 2 +- src/sage/combinat/tutorial.py | 2 +- src/sage/geometry/lattice_polytope.py | 172 +++++++++++++++---------- src/sage/schemes/toric/fano_variety.py | 28 ++-- 5 files changed, 123 insertions(+), 83 deletions(-) diff --git a/src/sage/categories/primer.py b/src/sage/categories/primer.py index c0f20e76107..8c7dc0c2b5f 100644 --- a/src/sage/categories/primer.py +++ b/src/sage/categories/primer.py @@ -84,7 +84,7 @@ sage: A = random_matrix(ZZ, 6, 3, x=7) # needs sage.modules sage: L = LatticePolytope(A.rows()) # needs sage.geometry.polyhedron sage.modules - sage: L.npoints() # oops! # random # needs sage.geometry.polyhedron sage.modules + sage: L.n_points() # oops! # random # needs sage.geometry.polyhedron sage.modules 37 - How to ensure robustness? diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index 2f8b7785cf0..d06bd1d609b 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -48,7 +48,7 @@ sage: points = random_matrix(ZZ, 6, 3, x=7).rows() # needs sage.modules sage: L = LatticePolytope(points) # needs sage.geometry.polyhedron sage.modules - sage: L.npoints(); L.plot3d() # random # needs sage.geometry.polyhedron sage.modules sage.plot + sage: L.n_points(); L.plot3d() # random # needs sage.geometry.polyhedron sage.modules sage.plot :ref:`Root systems, Coxeter and Weyl groups `:: diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index e2f3413e728..c60c3e83f34 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -1635,7 +1635,7 @@ M(4, 2, 3), M(5, 2, 3) in 3-d lattice M - sage: L.npoints() # random + sage: L.n_points() # random 11 This polytope can be visualized in 3D with ``L.plot3d()`` (see diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 5b4a6ec5847..854e85aaf0f 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -130,6 +130,7 @@ import shlex from sage.arith.misc import GCD as gcd +from sage.misc.superseded import deprecated_function_alias from sage.features import PythonModule from sage.features.palp import PalpExecutable from sage.features.databases import DatabaseReflexivePolytopes @@ -259,7 +260,7 @@ def LatticePolytope(data, compute_vertices=True, n=0, lattice=None): sage: points.append((0,0,0)) sage: p = LatticePolytope(points) - sage: p.nvertices() + sage: p.n_vertices() 6 You can suppress vertex computation for speed but this can lead to @@ -267,7 +268,7 @@ def LatticePolytope(data, compute_vertices=True, n=0, lattice=None): sage: p = LatticePolytope(points, compute_vertices=False) ... - sage: p.nvertices() + sage: p.n_vertices() 7 Given points must be in the lattice:: @@ -299,9 +300,9 @@ def LatticePolytope(data, compute_vertices=True, n=0, lattice=None): -1-d lattice polytope in 3-d lattice M sage: p.lattice_dim() 3 - sage: p.npoints() + sage: p.n_points() 0 - sage: p.nfacets() + sage: p.n_facets() 0 sage: p.points() Empty collection @@ -562,7 +563,7 @@ def __init__(self, points=None, compute_vertices=None, p.set_immutable() points = PointCollection(points, M) self._vertices = points - self._ambient_vertex_indices = tuple(range(self.nvertices())) + self._ambient_vertex_indices = tuple(range(self.n_vertices())) self._ambient_facet_indices = () else: self._ambient = ambient @@ -704,8 +705,6 @@ def __reduce__(self): """ state = self.__dict__.copy() state.pop('_vertices') - state.pop('_distances', None) - state.pop('_skeleton', None) try: state['_npoints'] = len(state['_points']) state.pop('_points') @@ -823,7 +822,7 @@ def _compute_facets(self): polar._polar = self self._polar = polar polar._facet_normals = self._vertices - ones = [1] * self.nvertices() + ones = [1] * self.n_vertices() ones = (ZZ**len(ones))(ones) ones.set_immutable() polar._facet_constants = ones @@ -1190,11 +1189,11 @@ def _read_equations(self, data): self._polar = polar self._facet_normals = polar._vertices polar._facet_normals = self._vertices - ones = [1] * polar.nvertices() + ones = [1] * polar.n_vertices() ones = (ZZ**len(ones))(ones) ones.set_immutable() self._facet_constants = ones - ones = [1] * self.nvertices() + ones = [1] * self.n_vertices() ones = (ZZ**len(ones))(ones) ones.set_immutable() polar._facet_constants = ones @@ -1257,8 +1256,8 @@ def _read_nef_partitions(self, data): self._read_nef_partitions(f) f.close() return - nvertices = self.nvertices() - data.readline() # Skip M/N information + num_vertices = self.n_vertices() + data.readline() # Skip M/N information nef_vertices = read_palp_point_collection(data, self.lattice()) if self.vertices() != nef_vertices: raise RuntimeError("nef.x changed the order of vertices!") @@ -1272,8 +1271,8 @@ def _read_nef_partitions(self, data): continue start = line.find("V:") + 2 end = line.find(" ", start) # Find DOUBLE space - pvertices = Sequence(line[start:end].split(),int) - partition = [0] * nvertices + pvertices = Sequence(line[start:end].split(), int) + partition = [0] * num_vertices for v in pvertices: partition[v] = 1 partition = NefPartition(partition, self) @@ -1348,8 +1347,8 @@ def _sort_faces(self, faces): ....: print("Wrong order!") """ faces = tuple(faces) - if len(faces) > 1: # Otherwise there is nothing to sort - if faces[0].nvertices() == 1: + if len(faces) > 1: # Otherwise there is nothing to sort + if faces[0].n_vertices() == 1: faces = tuple(sorted(faces, key=lambda f: f._ambient_vertex_indices)) elif faces[0].dim() == self.dim() - 1 and \ @@ -1576,7 +1575,7 @@ def ambient_point_indices(self): True """ if self._ambient is self: - return tuple(range(self.npoints())) + return tuple(range(self.n_points())) points = self._ambient.points() point_to_index = {p: i for i, p in enumerate(points)} return tuple(point_to_index[p] for p in self.points()) @@ -1611,7 +1610,7 @@ def ambient_ordered_point_indices(self): in 3-d lattice N """ if self._ambient is self: - return tuple(range(self.npoints())) + return tuple(range(self.n_points())) points = self._ambient.points() point_to_index = {p: i for i, p in enumerate(points)} return tuple(point_to_index[p] for p in sorted(self.points())) @@ -1672,7 +1671,7 @@ def boundary_point_indices(self): """ return tuple(i for i, c in enumerate(self.distances().columns(copy=False)) - if len(c.nonzero_positions()) < self.nfacets()) + if len(c.nonzero_positions()) < self.n_facets()) def boundary_points(self): r""" @@ -1759,7 +1758,7 @@ def dim(self): sage: p.lattice_dim() 3 """ - nv = self.nvertices() + nv = self.n_vertices() return self._PPL().affine_dimension() if nv > 3 else nv - 1 def distances(self, point=None): @@ -1820,13 +1819,15 @@ def distances(self, point=None): if point is not None: return (vector(QQ, point) * self.facet_normals() + self.facet_constants()) + try: return self._distances except AttributeError: P = self.points() - n = self.npoints() - self._distances = matrix(ZZ, [F * P + vector(ZZ, [c]*n) - for F, c in zip(self.facet_normals(), self.facet_constants())]) + n = self.n_points() + self._distances = matrix(ZZ, [F * P + vector(ZZ, [c] * n) + for F, c in zip(self.facet_normals(), + self.facet_constants())]) self._distances.set_immutable() return self._distances @@ -2432,8 +2433,8 @@ def incidence_matrix(self): sage: o.incidence_matrix().base_ring() Integer Ring """ - incidence_matrix = matrix(ZZ, self.nvertices(), - self.nfacets(), 0) + incidence_matrix = matrix(ZZ, self.n_vertices(), + self.n_facets(), 0) for Hindex, normal in enumerate(self.facet_normals()): facet_constant = self.facet_constant(Hindex) @@ -2549,7 +2550,7 @@ def interior_point_indices(self): """ return tuple(i for i, c in enumerate(self.distances().columns(copy=False)) - if len(c.nonzero_positions()) == self.nfacets()) + if len(c.nonzero_positions()) == self.n_facets()) def interior_points(self): r""" @@ -2677,7 +2678,7 @@ def linearly_independent_vertices(self): return self.vertices().matrix().pivot_rows() def nef_partitions(self, keep_symmetric=False, keep_products=True, - keep_projections=True, hodge_numbers=False): + keep_projections=True, hodge_numbers=False): r""" Return 2-part nef-partitions of ``self``. @@ -2847,29 +2848,39 @@ def nef_x(self, keys): """ return self._palp("nef.x -f " + keys) - def nfacets(self): + def n_facets(self): r""" Return the number of facets of this polytope. EXAMPLES: The number of facets of the 3-dimensional octahedron:: sage: o = lattice_polytope.cross_polytope(3) - sage: o.nfacets() + sage: o.n_facets() 8 The number of facets of an interval is 2:: - sage: LatticePolytope(([1],[2])).nfacets() + sage: LatticePolytope(([1],[2])).n_facets() 2 Now consider a 2-dimensional diamond in a 3-dimensional space:: sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)]) - sage: p.nfacets() + sage: p.n_facets() 4 + + TESTS:: + + sage: LatticePolytope(([1],[2])).nfacets() + doctest:warning... + DeprecationWarning: nfacets is deprecated. Please use n_facets instead. + See https://github.com/sagemath/sage/issues/44444 for details. + 2 """ return len(self.facet_normals()) if self.dim() > 0 else 0 + nfacets = deprecated_function_alias(44444, n_facets) + @cached_method def normal_form(self, algorithm='palp_native', permutation=False): r""" @@ -3326,7 +3337,7 @@ def _palp_PM_max(self, check=False): from .palp_normal_form import _palp_PM_max return _palp_PM_max(self.vertex_facet_pairing_matrix(), check) - def npoints(self): + def n_points(self): r""" Return the number of lattice points of this polytope. @@ -3334,18 +3345,28 @@ def npoints(self): octahedron and its polar cube:: sage: o = lattice_polytope.cross_polytope(3) - sage: o.npoints() # needs palp + sage: o.n_points() # needs palp 7 sage: cube = o.polar() - sage: cube.npoints() # needs palp + sage: cube.n_points() # needs palp 27 + + TESTS:: + + sage: LatticePolytope(([1],[2])).npoints() + doctest:warning... + DeprecationWarning: npoints is deprecated. Please use n_points instead. + See https://github.com/sagemath/sage/issues/44444 for details. + 2 """ try: return self._npoints except AttributeError: return len(self.points()) - def nvertices(self): + npoints = deprecated_function_alias(44444, n_points) + + def n_vertices(self): r""" Return the number of vertices of this polytope. @@ -3353,14 +3374,24 @@ def nvertices(self): and its polar cube:: sage: o = lattice_polytope.cross_polytope(3) - sage: o.nvertices() + sage: o.n_vertices() 6 sage: cube = o.polar() - sage: cube.nvertices() + sage: cube.n_vertices() 8 + + TESTS:: + + sage: LatticePolytope(([1],[2])).nvertices() + doctest:warning... + DeprecationWarning: nvertices is deprecated. Please use n_vertices instead. + See https://github.com/sagemath/sage/issues/44444 for details. + 2 """ return len(self._vertices) + nvertices = deprecated_function_alias(44444, n_vertices) + @cached_method def origin(self): r""" @@ -3495,7 +3526,7 @@ def plot3d(self, Plot with facets of different colors:: - sage: c.plot3d(facet_colors=rainbow(c.nfacets(), 'rgbtuple')) # needs palp sage.plot + sage: c.plot3d(facet_colors=rainbow(c.n_facets(), 'rgbtuple')) # needs palp sage.plot Graphics3d Object It is also possible to plot lower dimensional polytops in 3D (let's @@ -3529,13 +3560,13 @@ def plot3d(self, elif dim == 3: vertices = self.vertices() if show_points or show_pindices: - points = self.points()[self.nvertices():] + points = self.points()[self.n_vertices():] else: vertices = [vector(ZZ, list(self.vertex(i))+[0]*(3-amb_dim)) - for i in range(self.nvertices())] + for i in range(self.n_vertices())] if show_points or show_pindices: points = [vector(ZZ, list(self.point(i))+[0]*(3-amb_dim)) - for i in range(self.nvertices(), self.npoints())] + for i in range(self.n_vertices(), self.n_points())] pplot = 0 if show_facets: if dim == 2: @@ -3543,7 +3574,7 @@ def plot3d(self, vertices, opacity=facet_opacity, rgbcolor=facet_color) elif dim == 3: if facet_colors is None: - facet_colors = [facet_color] * self.nfacets() + facet_colors = [facet_color] * self.n_facets() vertex_to_index = {v: i for i, v in enumerate(self.vertices())} for f, c in zip(self.facets(), facet_colors): pplot += IndexFaceSet([[vertex_to_index[v] for v in f.vertices(f.traverse_boundary())]], @@ -3574,7 +3605,7 @@ def plot3d(self, pplot += point3d(points, size=point_size, rgbcolor=point_color) if show_pindices: for i, p in enumerate(points): - pplot += text3d(i+self.nvertices(), bc+index_shift*(p-bc), rgbcolor=pindex_color) + pplot += text3d(i+self.n_vertices(), bc+index_shift*(p-bc), rgbcolor=pindex_color) return pplot def polyhedron(self, **kwds): @@ -3720,7 +3751,7 @@ def points(self, *args, **kwds): """ if not hasattr(self, "_points"): M = self.lattice() - nv = self.nvertices() + nv = self.n_vertices() self._points = points = self._vertices if self.dim() == 1: v = points[1] - points[0] @@ -3947,7 +3978,7 @@ def skeleton_points(self, k=1): 18, 19, 20, 21, 22, 23, 24, 25, 26] """ if k >= self.dim(): - return list(range(self.npoints())) + return list(range(self.n_points())) skeleton = set() for face in self.faces(dim=k): skeleton.update(face.ambient_point_indices()) @@ -4003,7 +4034,7 @@ def traverse_boundary(self): li = [self.faces(0)[0]] prev, next = sorted(zero_faces.intersection(li[0].adjacent())) li = [prev, li[0], next] - while len(li) < self.nvertices(): + while len(li) < self.n_vertices(): prev, next = zero_faces.intersection(li[-1].adjacent()) if next == li[-2]: next = prev @@ -4055,7 +4086,7 @@ def vertex_facet_pairing_matrix(self): [0 2 2 2 0 0] """ V = self.vertices() - nv = self.nvertices() + nv = self.n_vertices() PM = matrix(ZZ, [n * V + vector(ZZ, [c] * nv) for n, c in zip(self.facet_normals(), self.facet_constants())]) PM.set_immutable() @@ -4734,6 +4765,7 @@ def nabla_polar(self): """ return self.nabla().polar() + @cached_method def nablas(self): r""" Return the polytopes `\nabla_i` corresponding to ``self``. @@ -4766,18 +4798,14 @@ def nablas(self): M(0, 0, 1) in 3-d lattice M] """ - try: - return self._nablas - except AttributeError: - Delta_polar = self._Delta_polar - origin = [[0] * Delta_polar.dim()] - self._nablas = tuple(LatticePolytope( - [Delta_polar.vertex(j) for j in part] + origin, - lattice=Delta_polar.lattice()) - for part in self.parts()) - return self._nablas - - def nparts(self): + Delta_polar = self._Delta_polar + origin = [[0] * Delta_polar.dim()] + return tuple(LatticePolytope( + [Delta_polar.vertex(j) for j in part] + origin, + lattice=Delta_polar.lattice()) + for part in self.parts()) + + def n_parts(self): r""" Return the number of parts in ``self``. @@ -4788,11 +4816,23 @@ def nparts(self): sage: o = lattice_polytope.cross_polytope(3) sage: np = NefPartition([0, 0, 1, 0, 1, 1], o); np Nef-partition {0, 1, 3} ⊔ {2, 4, 5} + sage: np.n_parts() + 2 + + TESTS:: + + sage: o = lattice_polytope.cross_polytope(3) + sage: np = NefPartition([0, 0, 1, 0, 1, 1], o) sage: np.nparts() + doctest:warning... + DeprecationWarning: nparts is deprecated. Please use n_parts instead. + See https://github.com/sagemath/sage/issues/44444 for details. 2 """ return self._nparts + nparts = deprecated_function_alias(44444, n_parts) + def part(self, i, all_points=False): r""" Return the ``i``-th part of ``self``. @@ -4862,7 +4902,7 @@ def parts(self, all_points=False): """ parts = [[] for _ in range(self._nparts)] if all_points: - for point in range(self._Delta_polar.npoints()): + for point in range(self._Delta_polar.n_points()): if point != self._Delta_polar.origin(): parts[self.part_of_point(point)].append(point) else: @@ -4933,9 +4973,9 @@ def part_of_point(self, i): ....: (0,-1,1), (-1,1,0), (0,-1,-1), (-1,-1,0), (-1,-1,2)]) sage: np = p.nef_partitions()[0]; np # needs palp Nef-partition {1, 2, 5, 7, 8} ⊔ {0, 3, 4, 6} - sage: p.nvertices() + sage: p.n_vertices() 9 - sage: p.npoints() # needs palp + sage: p.n_points() # needs palp 15 We see that the polytope has 6 more points in addition to vertices. One @@ -4950,14 +4990,14 @@ def part_of_point(self, i): But the remaining 5 are partitioned by ``np``:: - sage: [n for n in range(p.npoints()) # needs palp + sage: [n for n in range(p.n_points()) # needs palp ....: if p.origin() != n and np.part_of_point(n) == 0] [1, 2, 5, 7, 8, 9, 11, 13] - sage: [n for n in range(p.npoints()) # needs palp + sage: [n for n in range(p.n_points()) # needs palp ....: if p.origin() != n and np.part_of_point(n) == 1] [0, 3, 4, 6, 10, 12] """ - if i < self._Delta_polar.nvertices(): + if i < self._Delta_polar.n_vertices(): return self.part_of(i) if i == self._Delta_polar.origin(): raise ValueError("the origin belongs to all parts!") @@ -5375,7 +5415,7 @@ def all_points(polytopes): result = open(result_name) for p in polytopes: M = p.lattice() - nv = p.nvertices() + nv = p.n_vertices() if p.dim() == p.lattice_dim(): points = read_palp_point_collection(result, M) p._points = points if len(points) > nv else p.vertices() diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index c4823e6680f..355f7d593c1 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -502,16 +502,16 @@ def CPRFanoToricVariety(Delta=None, raise ValueError("Delta_polar must be reflexive!") # Check/normalize coordinate_points and construct fan rays if coordinate_points is None: - coordinate_points = list(range(Delta_polar.nvertices())) + coordinate_points = list(range(Delta_polar.n_vertices())) if charts is not None: for chart in charts: for point in chart: if point not in coordinate_points: coordinate_points.append(point) elif coordinate_points == "vertices": - coordinate_points = list(range(Delta_polar.nvertices())) + coordinate_points = list(range(Delta_polar.n_vertices())) elif coordinate_points == "all": - coordinate_points = list(range(Delta_polar.npoints())) + coordinate_points = list(range(Delta_polar.n_points())) coordinate_points.remove(Delta_polar.origin()) elif coordinate_points == "all but facets": coordinate_points = Delta_polar.skeleton_points(Delta_polar.dim() - 2) @@ -524,10 +524,10 @@ def CPRFanoToricVariety(Delta=None, raise ValueError( "no repetitions are allowed for coordinate points!\nGot: %s" % coordinate_points) - if not cp_set.issuperset(list(range(Delta_polar.nvertices()))): + if not cp_set.issuperset(list(range(Delta_polar.n_vertices()))): raise ValueError("all %d vertices of Delta_polar must be used " "for coordinates!\nGot: %s" - % (Delta_polar.nvertices(), coordinate_points)) + % (Delta_polar.n_vertices(), coordinate_points)) if Delta_polar.origin() in cp_set: raise ValueError("the origin (point #%d) cannot be used for a " "coordinate!\nGot: %s" @@ -1304,7 +1304,7 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, sage: F = GF(5^2, "a") # needs sage.rings.finite_rings sage: X = P1xP1.change_ring(F) # needs sage.rings.finite_rings sage: X.anticanonical_hypersurface(monomial_points='all', # needs sage.rings.finite_rings - ....: coefficients=[1]*X.Delta().npoints()) + ....: coefficients=[1]*X.Delta().n_points()) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: s^2*x^2 + s*t*x^2 + t^2*x^2 + s^2*x*y + s*t*x*y @@ -1318,11 +1318,11 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, Delta_polar = Delta.polar() # Monomial points normalization if monomial_points == "vertices": - monomial_points = list(range(Delta.nvertices())) + monomial_points = list(range(Delta.n_vertices())) elif monomial_points == "all": - monomial_points = list(range(Delta.npoints())) + monomial_points = list(range(Delta.n_points())) elif monomial_points == "vertices+origin": - monomial_points = list(range(Delta.nvertices())) + monomial_points = list(range(Delta.n_vertices())) monomial_points.append(Delta.origin()) elif monomial_points == "simplified" or monomial_points is None: monomial_points = Delta.skeleton_points(Delta.dim() - 2) @@ -1431,7 +1431,7 @@ def __init__(self, P_Delta, nef_partition, raise ValueError("polytopes 'Delta' of the nef-partition and the " "CPR-Fano toric variety must be the same!") self._nef_partition = nef_partition - k = nef_partition.nparts() + k = nef_partition.n_parts() # Pre-normalize all parameters if isinstance(monomial_points, str): monomial_points = [monomial_points] * k @@ -1448,13 +1448,13 @@ def __init__(self, P_Delta, nef_partition, Delta_i = nef_partition.Delta(i) # Monomial points normalization if monomial_points[i] == "vertices": - monomial_points[i] = list(range(Delta_i.nvertices())) + monomial_points[i] = list(range(Delta_i.n_vertices())) elif monomial_points[i] == "all": - monomial_points[i] = list(range(Delta_i.npoints())) + monomial_points[i] = list(range(Delta_i.n_points())) elif monomial_points[i] == "vertices+origin": - monomial_points[i] = list(range(Delta_i.nvertices())) + monomial_points[i] = list(range(Delta_i.n_vertices())) if (Delta_i.origin() is not None - and Delta_i.origin() >= Delta_i.nvertices()): + and Delta_i.origin() >= Delta_i.n_vertices()): monomial_points[i].append(Delta_i.origin()) elif isinstance(monomial_points[i], str): raise ValueError("'%s' is an unsupported description of " From b1ee4e5ddd0aed1c0d5268ff404da475daf17ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 23 Sep 2025 09:59:12 +0200 Subject: [PATCH 2/5] fix PR number --- src/sage/geometry/lattice_polytope.py | 16 ++++++++-------- src/sage/geometry/polyhedron/base2.py | 5 ++++- src/sage/geometry/polyhedron/base_QQ.py | 5 ++++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 854e85aaf0f..245a34dc963 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2874,12 +2874,12 @@ def n_facets(self): sage: LatticePolytope(([1],[2])).nfacets() doctest:warning... DeprecationWarning: nfacets is deprecated. Please use n_facets instead. - See https://github.com/sagemath/sage/issues/44444 for details. + See https://github.com/sagemath/sage/issues/40875 for details. 2 """ return len(self.facet_normals()) if self.dim() > 0 else 0 - nfacets = deprecated_function_alias(44444, n_facets) + nfacets = deprecated_function_alias(40875, n_facets) @cached_method def normal_form(self, algorithm='palp_native', permutation=False): @@ -3356,7 +3356,7 @@ def n_points(self): sage: LatticePolytope(([1],[2])).npoints() doctest:warning... DeprecationWarning: npoints is deprecated. Please use n_points instead. - See https://github.com/sagemath/sage/issues/44444 for details. + See https://github.com/sagemath/sage/issues/40875 for details. 2 """ try: @@ -3364,7 +3364,7 @@ def n_points(self): except AttributeError: return len(self.points()) - npoints = deprecated_function_alias(44444, n_points) + npoints = deprecated_function_alias(40875, n_points) def n_vertices(self): r""" @@ -3385,12 +3385,12 @@ def n_vertices(self): sage: LatticePolytope(([1],[2])).nvertices() doctest:warning... DeprecationWarning: nvertices is deprecated. Please use n_vertices instead. - See https://github.com/sagemath/sage/issues/44444 for details. + See https://github.com/sagemath/sage/issues/40875 for details. 2 """ return len(self._vertices) - nvertices = deprecated_function_alias(44444, n_vertices) + nvertices = deprecated_function_alias(40875, n_vertices) @cached_method def origin(self): @@ -4826,12 +4826,12 @@ def n_parts(self): sage: np.nparts() doctest:warning... DeprecationWarning: nparts is deprecated. Please use n_parts instead. - See https://github.com/sagemath/sage/issues/44444 for details. + See https://github.com/sagemath/sage/issues/40875 for details. 2 """ return self._nparts - nparts = deprecated_function_alias(44444, n_parts) + nparts = deprecated_function_alias(40875, n_parts) def part(self, i, all_points=False): r""" diff --git a/src/sage/geometry/polyhedron/base2.py b/src/sage/geometry/polyhedron/base2.py index f2626b6efa3..79be36c503e 100644 --- a/src/sage/geometry/polyhedron/base2.py +++ b/src/sage/geometry/polyhedron/base2.py @@ -346,7 +346,8 @@ def integral_points_count(self, **kwds): r""" Return the number of integral points in the polyhedron. - This generic version of this method simply calls :meth:`integral_points`. + This generic version of this method simply calls + :meth:`integral_points`. EXAMPLES:: @@ -383,6 +384,8 @@ def integral_points_count(self, **kwds): """ return len(self.integral_points()) + n_points = integral_points_count + def integral_points(self, threshold=100000): r""" Return the integral points in the polyhedron. diff --git a/src/sage/geometry/polyhedron/base_QQ.py b/src/sage/geometry/polyhedron/base_QQ.py index e54c1237cf1..1cfd34e5341 100644 --- a/src/sage/geometry/polyhedron/base_QQ.py +++ b/src/sage/geometry/polyhedron/base_QQ.py @@ -81,7 +81,8 @@ def _is_positive(self, x): _base_ring = QQ def integral_points_count(self, verbose=False, use_Hrepresentation=False, - explicit_enumeration_threshold=1000, preprocess=True, **kwds): + explicit_enumeration_threshold=1000, + preprocess=True, **kwds): r""" Return the number of integral points in the polyhedron. @@ -211,6 +212,8 @@ def integral_points_count(self, verbose=False, use_Hrepresentation=False, verbose=verbose, **kwds) + n_points = integral_points_count + @cached_method(do_pickle=True) def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, dual=None, irrational_primal=None, From 50fc3ee610eaf0c3034bd761db3bbd50068e05a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 23 Sep 2025 10:03:53 +0200 Subject: [PATCH 3/5] undo one change --- src/sage/geometry/lattice_polytope.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 245a34dc963..cb724d18c48 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -705,6 +705,7 @@ def __reduce__(self): """ state = self.__dict__.copy() state.pop('_vertices') + state.pop('_distances', None) try: state['_npoints'] = len(state['_points']) state.pop('_points') From 26a6d128bd966ad3ac47f5f97a17e01f076805d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 25 Sep 2025 13:22:26 +0200 Subject: [PATCH 4/5] undo the deprecations --- src/sage/geometry/cone.py | 12 ++++++++- src/sage/geometry/lattice_polytope.py | 37 ++++++++++++--------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index d1b61d41eb3..cd26042b1cd 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1061,7 +1061,7 @@ def lattice_dim(self): ambient_dim = lattice_dim - def nrays(self): + def n_rays(self) -> int: r""" Return the number of rays of ``self``. @@ -1069,12 +1069,22 @@ def nrays(self): EXAMPLES:: + sage: c = Cone([(1,0), (0,1)]) + sage: c.n_rays() + 2 + + TESTS: + + The old method name is kept as an alias:: + sage: c = Cone([(1,0), (0,1)]) sage: c.nrays() 2 """ return len(self._rays) + nrays = n_rays + def plot(self, **options): r""" Plot ``self``. diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index cb724d18c48..43a9c64d6fe 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -130,7 +130,6 @@ import shlex from sage.arith.misc import GCD as gcd -from sage.misc.superseded import deprecated_function_alias from sage.features import PythonModule from sage.features.palp import PalpExecutable from sage.features.databases import DatabaseReflexivePolytopes @@ -2870,17 +2869,16 @@ def n_facets(self): sage: p.n_facets() 4 - TESTS:: + TESTS: + + The old method name is kept as an alias:: sage: LatticePolytope(([1],[2])).nfacets() - doctest:warning... - DeprecationWarning: nfacets is deprecated. Please use n_facets instead. - See https://github.com/sagemath/sage/issues/40875 for details. 2 """ return len(self.facet_normals()) if self.dim() > 0 else 0 - nfacets = deprecated_function_alias(40875, n_facets) + nfacets = n_facets @cached_method def normal_form(self, algorithm='palp_native', permutation=False): @@ -3352,12 +3350,11 @@ def n_points(self): sage: cube.n_points() # needs palp 27 - TESTS:: + TESTS: + + The old method name is kept as an alias:: sage: LatticePolytope(([1],[2])).npoints() - doctest:warning... - DeprecationWarning: npoints is deprecated. Please use n_points instead. - See https://github.com/sagemath/sage/issues/40875 for details. 2 """ try: @@ -3365,7 +3362,7 @@ def n_points(self): except AttributeError: return len(self.points()) - npoints = deprecated_function_alias(40875, n_points) + npoints = n_points def n_vertices(self): r""" @@ -3381,17 +3378,16 @@ def n_vertices(self): sage: cube.n_vertices() 8 - TESTS:: + TESTS: + + The old method name is kept as an alias:: sage: LatticePolytope(([1],[2])).nvertices() - doctest:warning... - DeprecationWarning: nvertices is deprecated. Please use n_vertices instead. - See https://github.com/sagemath/sage/issues/40875 for details. 2 """ return len(self._vertices) - nvertices = deprecated_function_alias(40875, n_vertices) + nvertices = n_vertices @cached_method def origin(self): @@ -4820,19 +4816,18 @@ def n_parts(self): sage: np.n_parts() 2 - TESTS:: + TESTS: + + The old method name is kept as an alias:: sage: o = lattice_polytope.cross_polytope(3) sage: np = NefPartition([0, 0, 1, 0, 1, 1], o) sage: np.nparts() - doctest:warning... - DeprecationWarning: nparts is deprecated. Please use n_parts instead. - See https://github.com/sagemath/sage/issues/40875 for details. 2 """ return self._nparts - nparts = deprecated_function_alias(40875, n_parts) + nparts = n_parts def part(self, i, all_points=False): r""" From e68b6a1d66f72c0ea2f8c2bb4a9b5e771dd910fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 25 Sep 2025 13:31:18 +0200 Subject: [PATCH 5/5] further name changes + alias in geometry --- src/sage/geometry/cone.py | 36 +++++----- src/sage/geometry/cone_critical_angles.py | 12 ++-- src/sage/geometry/fan.py | 88 +++++++++++++---------- src/sage/geometry/fan_isomorphism.py | 6 +- src/sage/geometry/fan_morphism.py | 20 +++--- 5 files changed, 87 insertions(+), 75 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index cd26042b1cd..933f3341613 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1501,7 +1501,7 @@ def __init__(self, rays=None, lattice=None, if ambient is None: superinit(rays, lattice) self._ambient = self - self._ambient_ray_indices = tuple(range(self.nrays())) + self._ambient_ray_indices = tuple(range(self.n_rays())) else: self._ambient = ambient self._ambient_ray_indices = tuple(ambient_ray_indices) @@ -2038,7 +2038,7 @@ def _sort_faces(self, faces): """ faces = tuple(faces) if len(faces) > 1: # Otherwise there is nothing to sort - if faces[0].nrays() == 1: + if faces[0].n_rays() == 1: faces = tuple(sorted(faces, key=lambda f: f._ambient_ray_indices)) elif faces[0].dim() == self.dim() - 1 and \ @@ -2960,7 +2960,7 @@ def incidence_matrix(self): Integer Ring """ normals = self.facet_normals() - incidence_matrix = matrix(ZZ, self.nrays(), + incidence_matrix = matrix(ZZ, self.n_rays(), len(normals), 0) for Hindex, normal in enumerate(self.facet_normals()): @@ -3269,7 +3269,7 @@ def is_simplicial(self) -> bool: sage: cone2.is_simplicial() False """ - return self.nrays() == self.dim() + return self.n_rays() == self.dim() @cached_method def is_smooth(self) -> bool: @@ -3304,7 +3304,7 @@ def is_smooth(self) -> bool: """ if not self.is_simplicial(): return False - return self.rays().matrix().elementary_divisors() == [1] * self.nrays() + return self.rays().matrix().elementary_divisors() == [1] * self.n_rays() def is_empty(self): """ @@ -3331,10 +3331,10 @@ def is_trivial(self) -> bool: sage: c0 = cones.trivial(3) sage: c0.is_trivial() True - sage: c0.nrays() + sage: c0.n_rays() 0 """ - return self.nrays() == 0 + return self.n_rays() == 0 is_compact = is_trivial @@ -3448,7 +3448,7 @@ def plot(self, **options): deg = self.lattice().degree() tp = ToricPlotter(options, deg, self.rays()) # Modify ray labels to match the ambient cone or fan. - tp.ray_label = label_list(tp.ray_label, self.nrays(), deg <= 2, + tp.ray_label = label_list(tp.ray_label, self.n_rays(), deg <= 2, self.ambient_ray_indices()) result = tp.plot_lattice() + tp.plot_generators() # To deal with non-strictly convex cones we separate rays and labels. @@ -3693,7 +3693,7 @@ def solid_restriction(self): the original:: sage: K = random_cone(max_ambient_dim=6) - sage: K.solid_restriction().nrays() == K.nrays() + sage: K.solid_restriction().n_rays() == K.n_rays() True The solid restriction of a cone has the same lineality as the @@ -4330,7 +4330,7 @@ def semigroup_generators(self): if not self.is_simplicial(): from sage.geometry.triangulation.point_configuration \ import PointConfiguration - origin = self.nrays() # last one in pc + origin = self.n_rays() # last one in pc pc = PointConfiguration(tuple(self.rays()) + (N(0),), star=origin) triangulation = pc.triangulate() subcones = ( Cone(( self.ray(i) for i in simplex if i != origin ), @@ -4370,7 +4370,7 @@ def Hilbert_basis(self): - a :class:`~sage.geometry.point_collection.PointCollection`. The - rays of ``self`` are the first ``self.nrays()`` entries. + rays of ``self`` are the first ``self.n_rays()`` entries. EXAMPLES: @@ -6483,7 +6483,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, Likewise for the number of rays when ``min_rays == max_rays``:: sage: K = random_cone(min_rays=3, max_rays=3) - sage: K.nrays() + sage: K.n_rays() 3 If we specify a lattice, then the returned cone will live in it:: @@ -6514,7 +6514,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, ....: strictly_convex=False, solid=True) sage: 4 <= K.lattice_dim() and K.lattice_dim() <= 7 True - sage: 2 <= K.nrays() and K.nrays() <= 10 + sage: 2 <= K.n_rays() and K.n_rays() <= 10 True sage: K.is_strictly_convex() False @@ -6536,7 +6536,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, ....: min_rays=3, max_rays=4) sage: 5 <= K.lattice_dim() and K.lattice_dim() <= 8 True - sage: 3 <= K.nrays() and K.nrays() <= 4 + sage: 3 <= K.n_rays() and K.n_rays() <= 4 True Ensure that an exception is raised when either lower bound is greater @@ -6616,7 +6616,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, sage: _initial_seed = initial_seed() sage: set_random_seed(8) sage: K = random_cone(max_ambient_dim=3, min_rays=7) - sage: K.nrays() >= 7 + sage: K.n_rays() >= 7 True sage: K.lattice_dim() 3 @@ -6855,8 +6855,8 @@ def is_valid(K): else: if K.lattice() is not lattice: return False - return all([K.nrays() >= min_rays, - max_rays is None or K.nrays() <= max_rays, + return all([K.n_rays() >= min_rays, + max_rays is None or K.n_rays() <= max_rays, solid is None or K.is_solid() == solid, strictly_convex is None or K.is_strictly_convex() == strictly_convex]) @@ -6920,7 +6920,7 @@ def is_valid(K): # mangle what we have, we just start over if we get a cone # that won't work. # - while r > K.nrays() and not K.is_full_space(): + while r > K.n_rays() and not K.is_full_space(): rays.append(L.random_element()) K = Cone(rays, lattice=L) rays = list(K.rays()) # Avoid re-normalizing next time around diff --git a/src/sage/geometry/cone_critical_angles.py b/src/sage/geometry/cone_critical_angles.py index 11ed0c3c4ab..367d97762bb 100644 --- a/src/sage/geometry/cone_critical_angles.py +++ b/src/sage/geometry/cone_critical_angles.py @@ -231,7 +231,7 @@ def gevp_licis(G): sage: from sage.geometry.cone_critical_angles import gevp_licis sage: K = cones.nonnegative_orthant(3) sage: G = matrix.column(K.rays()) - sage: len(list(gevp_licis(G))) == 2^(K.nrays()) - 1 + sage: len(list(gevp_licis(G))) == 2^(K.n_rays()) - 1 True TESTS: @@ -647,8 +647,8 @@ def compute_gevp_M(gs, hs): sage: hs = [h.change_ring(QQ) for h in Q] sage: M = compute_gevp_M(gs, hs)[0] sage: all( M[i][j] == gs[i].inner_product(hs[j]) - ....: for i in range(P.nrays()) - ....: for j in range(Q.nrays()) ) + ....: for i in range(P.n_rays()) + ....: for j in range(Q.n_rays()) ) True TESTS: @@ -670,7 +670,7 @@ def compute_gevp_M(gs, hs): sage: hs = [h.change_ring(QQ) for h in Q] sage: M = compute_gevp_M(gs,hs)[0] sage: f = lambda i,j: gs[i].inner_product(hs[j]) - sage: expected_M = matrix(QQ, P.nrays(), Q.nrays(), f) + sage: expected_M = matrix(QQ, P.n_rays(), Q.n_rays(), f) sage: M == expected_M True sage: G = matrix.column(gs) @@ -954,11 +954,11 @@ def max_angle(P, Q, exact, epsilon): for I in G_index_sets: G_I = G.matrix_from_columns(I) - I_complement = [i for i in range(P.nrays()) if i not in I] + I_complement = [i for i in range(P.n_rays()) if i not in I] G_I_c_T = G.matrix_from_columns(I_complement).transpose() for J in H_index_sets: - J_complement = [j for j in range(Q.nrays()) if j not in J] + J_complement = [j for j in range(Q.n_rays()) if j not in J] H_J = H.matrix_from_columns(J) H_J_c_T = H.matrix_from_columns(J_complement).transpose() diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 7af1fa122ee..b4f00a3bab4 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -206,13 +206,13 @@ Let's see how "different" are ``fan2`` and ``fan4``:: - sage: fan2.ngenerating_cones() + sage: fan2.n_generating_cones() 6 - sage: fan2.nrays() + sage: fan2.n_rays() 8 - sage: fan4.ngenerating_cones() # needs palp + sage: fan4.n_generating_cones() # needs palp 48 - sage: fan4.nrays() # needs palp + sage: fan4.n_rays() # needs palp 26 Smoothness does not come for free! @@ -404,14 +404,14 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, other cones), use ``discard_faces=True`` option:: sage: P2 = Fan([cone1, cone2, cone2], discard_faces=True) - sage: P2.ngenerating_cones() + sage: P2.n_generating_cones() 2 However, in this case it was definitely a typo, since the fan of `\mathbb{P}^2` has 3 maximal cones:: sage: P2 = Fan([cone1, cone2, cone3]) - sage: P2.ngenerating_cones() + sage: P2.n_generating_cones() 3 Looks better. An alternative way is :: @@ -419,7 +419,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, sage: rays = [(1,0), (0,1), (-1,-1)] sage: cones = [(0,1), (1,2), (2,0)] sage: P2a = Fan(cones, rays) - sage: P2a.ngenerating_cones() + sage: P2a.n_generating_cones() 3 sage: P2 == P2a False @@ -434,7 +434,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, Yet another way to construct this fan is :: sage: P2b = Fan(cones, rays, check=False) - sage: P2b.ngenerating_cones() + sage: P2b.n_generating_cones() 3 sage: P2a == P2b True @@ -498,7 +498,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, Let's construct the fan using ``allow_arrangement=True`` option:: sage: fan = Fan([c1, c2], allow_arrangement=True) - sage: fan.ngenerating_cones() + sage: fan.n_generating_cones() 5 Another example where cone c2 is inside cone c1:: @@ -506,7 +506,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, sage: c1 = Cone([(4, 0, 0), (0, 4, 0), (0, 0, 4)]) sage: c2 = Cone([(2, 1, 1), (1, 2, 1), (1, 1, 2)]) sage: fan = Fan([c1, c2], allow_arrangement=True) - sage: fan.ngenerating_cones() + sage: fan.n_generating_cones() 7 sage: fan.plot() # needs sage.plot Graphics3d Object @@ -599,7 +599,7 @@ def result(): # Optimization for fans generated by a single cone if len(cones) == 1 and rays is None: cone = cones[0] - cones = (tuple(range(cone.nrays())), ) + cones = (tuple(range(cone.n_rays())), ) rays = cone.rays() is_complete = lattice.dimension() == 0 return result() @@ -1116,7 +1116,7 @@ def star_generator_indices(self): """ if "_star_generator_indices" not in self.__dict__: fan = self.ambient() - sgi = set(range(fan.ngenerating_cones())) + sgi = set(range(fan.n_generating_cones())) for ray in self.ambient_ray_indices(): sgi.intersection_update(fan._ray_to_cones(ray)) self._star_generator_indices = tuple(sorted(sgi)) @@ -1500,7 +1500,7 @@ def FanFace(rays, cones): new_order = [n for n in new_order if n not in tail] + tail # Make sure that rays are in the beginning in proper order head = [rays_to_index[()]] # Empty face - head.extend(rays_to_index[(n,)] for n in range(self.nrays())) + head.extend(rays_to_index[(n,)] for n in range(self.n_rays())) new_order = head + [n for n in new_order if n not in head] # "Invert" this list to a dictionary labels = {old: new for new, old in enumerate(new_order)} @@ -1513,7 +1513,7 @@ def FanFace(rays, cones): # We need "special treatment" for the whole fan. If we added its # ray incidence information to the total list, it would be # confused with the generating cone in the case of a single cone. - elements[labels[0]] = FanFace(tuple(range(self.nrays())), ()) + elements[labels[0]] = FanFace(tuple(range(self.n_rays())), ()) D = dict(enumerate(elements)) L.relabel(D) self._cone_lattice = FinitePoset(L, elements, key=id(self)) @@ -1662,13 +1662,13 @@ def cartesian_product(self, other, lattice=None): ....: cones=[[0,1], [1,2], [2,0]], lattice=L) sage: fan1.cartesian_product(fan2) Rational polyhedral fan in 3-d lattice K+L - sage: _.ngenerating_cones() + sage: _.n_generating_cones() 6 """ assert isinstance(other, RationalPolyhedralFan) rc = super().cartesian_product(other, lattice) self_cones = [cone.ambient_ray_indices() for cone in self] - n = self.nrays() + n = self.n_rays() other_cones = [tuple(n + i for i in cone.ambient_ray_indices()) for cone in other] new_cones = [c1 + c2 for c1 in self_cones for c2 in other_cones] @@ -1730,18 +1730,18 @@ def common_refinement(self, other): sage: F3 = F2.cartesian_product(F1) sage: F4 = F1.cartesian_product(F2) sage: FF = F3.common_refinement(F4) - sage: F3.ngenerating_cones() + sage: F3.n_generating_cones() 10 - sage: F4.ngenerating_cones() + sage: F4.n_generating_cones() 10 - sage: FF.ngenerating_cones() + sage: FF.n_generating_cones() 13 An example with two non-complete fans with the same support:: sage: F5 = Fan2d([(1,0), (1,2), (0,1)]) sage: F6 = Fan2d([(1,0), (2,1), (0,1)]) - sage: F5.common_refinement(F6).ngenerating_cones() + sage: F5.common_refinement(F6).n_generating_cones() 3 Both fans must live in the same lattice:: @@ -1987,7 +1987,7 @@ def cone_containing(self, *points): try: rays = [int(_) for _ in points] # Got ray indices - generating_cones = set(range(self.ngenerating_cones())) + generating_cones = set(range(self.n_generating_cones())) for ray in rays: generating_cones.intersection_update(self._ray_to_cones(ray)) if not generating_cones: @@ -2234,7 +2234,7 @@ def cones(self, dim=None, codim=None): # dimension (otherwise it is not very useful). if len(levels) >= 3: # There are cones of dimension higher than 1 top_cones = list(levels[-1]) - if len(top_cones) == self.ngenerating_cones(): + if len(top_cones) == self.n_generating_cones(): top_cones.sort(key=lambda cone: cone.star_generator_indices()[0]) levels[-1] = top_cones @@ -2413,7 +2413,7 @@ def embed(self, cone): # If there is a cone containing all of the rays of the given cone, # they must be among its generating rays and we only need to worry # if there are any extra ones. - if cone.nrays() != result.nrays(): + if cone.n_rays() != result.n_rays(): raise ValueError except ValueError: raise ValueError("%s does not belong to %s!" % (cone, self)) @@ -2681,7 +2681,7 @@ def is_equivalent(self, other) -> bool: """ if (self.lattice() != other.lattice() or self.dim() != other.dim() - or self.ngenerating_cones() != other.ngenerating_cones() + or self.n_generating_cones() != other.n_generating_cones() or self.rays().set() != other.rays().set() or self.virtual_rays().set() != other.virtual_rays().set()): return False @@ -2881,7 +2881,7 @@ def is_simplicial(self) -> bool: sage: fan = NormalFan(lattice_polytope.cross_polytope(3)) sage: fan.is_simplicial() False - sage: fan.generating_cone(0).nrays() + sage: fan.generating_cone(0).n_rays() 4 """ if "is_simplicial" not in self.__dict__: @@ -2965,17 +2965,17 @@ def make_simplicial(self, **kwds): sage: fan = NormalFan(lattice_polytope.cross_polytope(3)) sage: fan.is_simplicial() False - sage: fan.ngenerating_cones() + sage: fan.n_generating_cones() 6 sage: new_fan = fan.make_simplicial() sage: new_fan.is_simplicial() True - sage: new_fan.ngenerating_cones() + sage: new_fan.n_generating_cones() 12 """ return self.subdivide(make_simplicial=True, **kwds) - def ngenerating_cones(self): + def n_generating_cones(self) -> int: r""" Return the number of generating cones of ``self``. @@ -2984,8 +2984,18 @@ def ngenerating_cones(self): EXAMPLES:: sage: fan = toric_varieties.P1xP1().fan() # needs palp - sage: fan.ngenerating_cones() # needs palp + sage: fan.n_generating_cones() # needs palp 4 + sage: cone1 = Cone([(1,0), (0,1)]) + sage: cone2 = Cone([(-1,0)]) + sage: fan = Fan([cone1, cone2]) + sage: fan.n_generating_cones() + 2 + + TESTS: + + The old method name is kept as an alias:: + sage: cone1 = Cone([(1,0), (0,1)]) sage: cone2 = Cone([(-1,0)]) sage: fan = Fan([cone1, cone2]) @@ -2994,6 +3004,8 @@ def ngenerating_cones(self): """ return len(self.generating_cones()) + ngenerating_cones = n_generating_cones + def plot(self, **options): r""" Plot ``self``. @@ -3050,16 +3062,16 @@ def subdivide(self, new_rays=None, make_simplicial=False, sage: fan = NormalFan(lattice_polytope.cross_polytope(3)) sage: fan.is_simplicial() False - sage: fan.ngenerating_cones() + sage: fan.n_generating_cones() 6 - sage: fan.nrays() + sage: fan.n_rays() 8 sage: new_fan = fan.subdivide(new_rays=[(1,0,0)]) sage: new_fan.is_simplicial() False - sage: new_fan.ngenerating_cones() + sage: new_fan.n_generating_cones() 9 - sage: new_fan.nrays() + sage: new_fan.n_rays() 9 TESTS: @@ -3239,7 +3251,7 @@ def is_in_SR(I): # 2) if you remove any one entry j, then I-{j} is contained in a facet facets = [frozenset(c.ambient_ray_indices()) for c in self.generating_cones()] - all_points = frozenset(range(self.nrays())) + all_points = frozenset(range(self.n_rays())) d_max = max(map(len, facets)) + 1 SR = [] for d in range(1, d_max): @@ -3267,7 +3279,7 @@ def Stanley_Reisner_ideal(self, ring): INPUT: - - A polynomial ring in ``self.nrays()`` variables. + - A polynomial ring in ``self.n_rays()`` variables. OUTPUT: the Stanley-Reisner ideal in the given polynomial ring @@ -3289,7 +3301,7 @@ def linear_equivalence_ideal(self, ring): INPUT: - - A polynomial ring in ``self.nrays()`` variables. + - A polynomial ring in ``self.n_rays()`` variables. OUTPUT: @@ -3308,7 +3320,7 @@ def linear_equivalence_ideal(self, ring): gens = [] for d in range(self.dim()): gens.append(sum([self.ray(i)[d] * ring.gen(i) - for i in range(self.nrays())])) + for i in range(self.n_rays())])) return ring.ideal(gens) def oriented_boundary(self, cone): @@ -3638,7 +3650,7 @@ def discard_faces(cones): sage: from sage.geometry.fan import discard_faces sage: len(discard_faces(cones)) # needs palp 3 - sage: Sigma.ngenerating_cones() # needs palp + sage: Sigma.n_generating_cones() # needs palp 3 """ # Convert to a list or make a copy, so that the input is unchanged. diff --git a/src/sage/geometry/fan_isomorphism.py b/src/sage/geometry/fan_isomorphism.py index bfea950aa00..6833f8ec4c9 100644 --- a/src/sage/geometry/fan_isomorphism.py +++ b/src/sage/geometry/fan_isomorphism.py @@ -44,9 +44,9 @@ def fan_isomorphic_necessary_conditions(fan1, fan2): return False if fan1.dim() != fan2.dim(): return False - if fan1.nrays() != fan2.nrays(): + if fan1.n_rays() != fan2.n_rays(): return False - if fan1.ngenerating_cones() != fan2.ngenerating_cones(): + if fan1.n_generating_cones() != fan2.n_generating_cones(): return False return fan1.is_complete() == fan2.is_complete() @@ -348,7 +348,7 @@ def fan_2d_echelon_forms(fan): sage: parent(list(_)[0]) Full MatrixSpace of 2 by 0 dense matrices over Integer Ring """ - if fan.nrays() == 0: + if fan.n_rays() == 0: return frozenset([fan_2d_echelon_form(fan)]) rays = list(fan_2d_cyclically_ordered_rays(fan)) echelon_forms = [] diff --git a/src/sage/geometry/fan_morphism.py b/src/sage/geometry/fan_morphism.py index ddefd299133..cb83d968b7f 100644 --- a/src/sage/geometry/fan_morphism.py +++ b/src/sage/geometry/fan_morphism.py @@ -176,7 +176,7 @@ class FanMorphism(FreeModuleMorphism): sage: fm = FanMorphism(phi, normal, face, subdivide=True) sage: fm.domain_fan() is normal False - sage: fm.domain_fan().ngenerating_cones() + sage: fm.domain_fan().n_generating_cones() 6 We had to subdivide two of the four cones of the normal fan, since @@ -532,13 +532,13 @@ def _ray_index_map(self): ValueError: ray #1 is mapped into a 2-d cone! """ Sigma = self.domain_fan() - ray_index_map = [-1] * Sigma.nrays() + ray_index_map = [-1] * Sigma.n_rays() for i, rho in enumerate(Sigma(1)): sigma_p = self.image_cone(rho) - if sigma_p.nrays() > 1: + if sigma_p.n_rays() > 1: raise ValueError("ray #%d is mapped into a %d-d cone!" % (i, sigma_p.dim())) - elif sigma_p.nrays() == 1: + elif sigma_p.n_rays() == 1: ray_index_map[i] = sigma_p.ambient_ray_indices()[0] return tuple(ray_index_map) @@ -693,7 +693,7 @@ def _subdivide_domain_fan(self, check, verbose): print("(%.3f ms)" % walltime(start)) print("Number of domain cones: %d.\n" "Number of chambers: %d." % - (domain_fan.ngenerating_cones(), len(chambers))) + (domain_fan.n_generating_cones(), len(chambers))) # Subdivide domain_cone. if verbose: start = walltime() @@ -735,7 +735,7 @@ def _subdivide_domain_fan(self, check, verbose): new_cones.extend(parts) if verbose: print("(%.3f ms)" % walltime(start)) - if len(new_cones) > domain_fan.ngenerating_cones(): + if len(new_cones) > domain_fan.n_generating_cones(): # Construct a new fan keeping old rays in the same order new_rays = list(domain_fan.rays()) for cone in new_cones: @@ -1194,8 +1194,8 @@ def is_bundle(self): Sigma = self.domain_fan() Sigma_p = self.codomain_fan() Sigma_0 = self.kernel_fan() - if (Sigma.ngenerating_cones() != - Sigma_0.ngenerating_cones() * Sigma_p.ngenerating_cones()): + if (Sigma.n_generating_cones() != + Sigma_0.n_generating_cones() * Sigma_p.n_generating_cones()): return False # Definitely no splitting. try: ray_index_map = self._ray_index_map() @@ -1560,7 +1560,7 @@ def preimage_cones(self, cone): CSGI = cone.star_generator_indices() RISGIS = self._RISGIS() domain_fan = self._domain_fan - possible_rays = frozenset(i for i in range(domain_fan.nrays()) + possible_rays = frozenset(i for i in range(domain_fan.n_rays()) if RISGIS[i].issuperset(CSGI)) preimage_cones = [] for dcones in domain_fan.cones(): @@ -1602,7 +1602,7 @@ def preimage_fan(self, cone): sage: fm.preimage_fan(Cone([(1,0)])).cones() ((0-d cone of Rational polyhedral fan in 2-d lattice N,), (1-d cone of Rational polyhedral fan in 2-d lattice N,)) - sage: fm.preimage_fan(quadrant_cone).ngenerating_cones() + sage: fm.preimage_fan(quadrant_cone).n_generating_cones() 2 sage: len(fm.preimage_cones(quadrant_cone)) 3