Skip to content

Commit 6f8fb9b

Browse files
author
Release Manager
committed
Trac #22067: generating function of integral points of polyhedra
Implement this using !MacMahon's Omega operator (#22066). URL: https://trac.sagemath.org/22067 Reported by: dkrenn Ticket author(s): Daniel Krenn Reviewer(s): Matthias Koeppe
2 parents 5544a33 + 6f97db0 commit 6f8fb9b

File tree

4 files changed

+1753
-3
lines changed

4 files changed

+1753
-3
lines changed

src/doc/en/reference/discrete_geometry/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Lattice polyhedra
4646
sage/geometry/polyhedron/palp_database
4747
sage/geometry/polyhedron/ppl_lattice_polygon
4848
sage/geometry/polyhedron/ppl_lattice_polytope
49+
sage/geometry/polyhedron/generating_function
4950

5051
Combinatorial Polyhedra
5152
~~~~~~~~~~~~~~~~~~~~~~~

src/sage/geometry/polyhedron/base2.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,3 +675,132 @@ def random_integral_point(self, **kwds):
675675
raise EmptySetError('polyhedron does not contain any integral points')
676676

677677
return self.get_integral_point(current_randstate().python_random().randint(0, count-1), **kwds)
678+
679+
def generating_function_of_integral_points(self, **kwds):
680+
r"""
681+
Return the multivariate generating function of the
682+
integral points of this polyhedron.
683+
684+
To be precise, this returns
685+
686+
.. MATH::
687+
688+
\sum_{(r_0,\dots,r_{d-1}) \in \mathit{polyhedron}\cap \ZZ^d}
689+
y_0^{r_0} \dots y_{d-1}^{r_{d-1}}.
690+
691+
This calls
692+
:func:`~sage.geometry.polyhedron.generating_function.generating_function_of_integral_points`,
693+
so have a look at the documentation and examples there.
694+
695+
INPUT:
696+
697+
The following keyword arguments are passed to
698+
:func:`~sage.geometry.polyhedron.generating_function.generating_function_of_integral_points`:
699+
700+
- ``split`` -- (default: ``False``) a boolean or list
701+
702+
- ``split=False`` computes the generating function directly,
703+
without any splitting.
704+
705+
- When ``split`` is a list of disjoint polyhedra, then
706+
for each of these polyhedra, this polyhedron is intersected with it,
707+
its generating function computed and all these generating functions
708+
are summed up.
709+
710+
- ``split=True`` splits into `d!` disjoint polyhedra.
711+
712+
- ``result_as_tuple`` -- (default: ``None``) a boolean or ``None``
713+
714+
This specifies whether the output is a (partial) factorization
715+
(``result_as_tuple=False``) or a sum of such (partial)
716+
factorizations (``result_as_tuple=True``). By default
717+
(``result_as_tuple=None``), this is automatically determined.
718+
If the output is a sum, it is represented as a tuple whose
719+
entries are the summands.
720+
721+
- ``indices`` -- (default: ``None``) a list or tuple
722+
723+
If this
724+
is ``None``, this is automatically determined.
725+
726+
- ``name`` -- (default: ``'y'``) a string
727+
728+
The variable names of the Laurent polynomial ring of the output
729+
are this string followed by an integer.
730+
731+
- ``names`` -- a list or tuple of names (strings), or a comma separated string
732+
733+
``name`` is extracted from ``names``, therefore ``names`` has to contain
734+
exactly one variable name, and ``name`` and``names`` cannot be specified
735+
both at the same time.
736+
737+
- ``Factorization_sort`` (default: ``False``) and
738+
``Factorization_simplify`` (default: ``True``) -- booleans
739+
740+
These are passed on to
741+
:class:`sage.structure.factorization.Factorization` when creating
742+
the result.
743+
744+
- ``sort_factors`` -- (default: ``False``) a boolean
745+
746+
If set, then
747+
the factors of the output are sorted such that the numerator is
748+
first and only then all factors of the denominator. It is ensured
749+
that the sorting is always the same; use this for doctesting.
750+
751+
OUTPUT:
752+
753+
The generating function as a (partial)
754+
:class:`~sage.structure.factorization.Factorization`
755+
of the result whose factors are Laurent polynomials
756+
757+
The result might be a tuple of such factorizations
758+
(depending on the parameter ``result_as_tuple``) as well.
759+
760+
.. NOTE::
761+
762+
At the moment, only polyhedra with nonnegative coordinates
763+
(i.e. a polyhedron in the nonnegative orthant) are handled.
764+
765+
EXAMPLES::
766+
767+
sage: P2 = (
768+
....: Polyhedron(ieqs=[(0, 0, 0, 1), (0, 0, 1, 0), (0, 1, 0, -1)]),
769+
....: Polyhedron(ieqs=[(0, -1, 0, 1), (0, 1, 0, 0), (0, 0, 1, 0)]))
770+
sage: P2[0].generating_function_of_integral_points(sort_factors=True)
771+
1 * (-y0 + 1)^-1 * (-y1 + 1)^-1 * (-y0*y2 + 1)^-1
772+
sage: P2[1].generating_function_of_integral_points(sort_factors=True)
773+
1 * (-y1 + 1)^-1 * (-y2 + 1)^-1 * (-y0*y2 + 1)^-1
774+
sage: (P2[0] & P2[1]).Hrepresentation()
775+
(An equation (1, 0, -1) x + 0 == 0,
776+
An inequality (1, 0, 0) x + 0 >= 0,
777+
An inequality (0, 1, 0) x + 0 >= 0)
778+
sage: (P2[0] & P2[1]).generating_function_of_integral_points(sort_factors=True)
779+
1 * (-y1 + 1)^-1 * (-y0*y2 + 1)^-1
780+
781+
The number of integer partitions
782+
`1 \leq r_0 \leq r_1 \leq r_2 \leq r_3 \leq r_4`::
783+
784+
sage: P = Polyhedron(ieqs=[(-1, 1, 0, 0, 0, 0), (0, -1, 1, 0, 0, 0),
785+
....: (0, 0, -1, 1, 0, 0), (0, 0, 0, -1, 1, 0),
786+
....: (0, 0, 0, 0, -1, 1)])
787+
sage: f = P.generating_function_of_integral_points(sort_factors=True); f
788+
y0*y1*y2*y3*y4 * (-y4 + 1)^-1 * (-y3*y4 + 1)^-1 * (-y2*y3*y4 + 1)^-1 *
789+
(-y1*y2*y3*y4 + 1)^-1 * (-y0*y1*y2*y3*y4 + 1)^-1
790+
sage: f = f.value()
791+
sage: P.<z> = PowerSeriesRing(ZZ)
792+
sage: c = f.subs({y: z for y in f.parent().gens()}); c
793+
z^5 + z^6 + 2*z^7 + 3*z^8 + 5*z^9 + 7*z^10 + 10*z^11 + 13*z^12 + 18*z^13 +
794+
23*z^14 + 30*z^15 + 37*z^16 + 47*z^17 + 57*z^18 + 70*z^19 + 84*z^20 +
795+
101*z^21 + 119*z^22 + 141*z^23 + 164*z^24 + O(z^25)
796+
sage: [Partitions(k, length=5).cardinality() for k in range(5,20)] == \
797+
....: c.truncate().coefficients(sparse=False)[5:20]
798+
True
799+
800+
.. SEEALSO::
801+
802+
More examples can be found at
803+
:func:`~sage.geometry.polyhedron.generating_function.generating_function_of_integral_points`.
804+
"""
805+
from .generating_function import generating_function_of_integral_points
806+
return generating_function_of_integral_points(self, **kwds)

0 commit comments

Comments
 (0)