Skip to content

Commit

Permalink
sage.geometry.integral_points: Fall back to generic impl if matrix_in…
Browse files Browse the repository at this point in the history
…teger_dense is not available
  • Loading branch information
Matthias Koeppe committed Feb 15, 2023
1 parent 525c625 commit 9a8b269
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#cython: wraparound=False, boundscheck=False
r"""
Cython helper methods to compute integral points in polyhedra.
"""
Expand All @@ -19,16 +18,11 @@ import itertools

from sage.matrix.constructor import matrix, column_matrix, vector, diagonal_matrix
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.rings.real_mpfr import RR
from sage.rings.integer cimport Integer
from sage.arith.misc import GCD as gcd
from sage.arith.misc import gcd
from sage.arith.functions import lcm
from sage.combinat.permutation import Permutation
from sage.misc.misc_c import prod
from sage.modules.free_module import FreeModule
from sage.modules.vector_integer_dense cimport Vector_integer_dense
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense

##############################################################################
# The basic idea to enumerate the lattice points in the parallelotope
Expand Down Expand Up @@ -140,8 +134,8 @@ cpdef tuple parallelotope_points(spanning_points, lattice):
sage: len(parallelotope_points(rays, ZZ^4))
967
"""
cdef Matrix_integer_dense VDinv
cdef Matrix_integer_dense R = matrix(spanning_points).transpose()
cdef MatrixClass VDinv
cdef MatrixClass R = matrix(spanning_points).transpose()
e, d, VDinv = ray_matrix_normal_form(R)
cdef tuple points = loop_over_parallelotope_points(e, d, VDinv, R, lattice)
for p in points:
Expand Down Expand Up @@ -183,8 +177,8 @@ cpdef tuple ray_matrix_normal_form(R):


# The optimized version avoids constructing new matrices, vectors, and lattice points
cpdef tuple loop_over_parallelotope_points(e, d, Matrix_integer_dense VDinv,
Matrix_integer_dense R, lattice,
cpdef tuple loop_over_parallelotope_points(e, d, MatrixClass VDinv,
MatrixClass R, lattice,
A=None, b=None):
r"""
The inner loop of :func:`parallelotope_points`.
Expand Down Expand Up @@ -224,7 +218,7 @@ cpdef tuple loop_over_parallelotope_points(e, d, Matrix_integer_dense VDinv,
s = ZZ.zero() # summation variable
cdef list gens = []
gen = lattice(ZZ.zero())
cdef Vector_integer_dense q_times_d = vector(ZZ, dim)
cdef VectorClass q_times_d = vector(ZZ, dim)
for base in itertools.product(*[ range(i) for i in e ]):
for i in range(dim):
s = ZZ.zero()
Expand Down Expand Up @@ -308,15 +302,15 @@ cpdef tuple simplex_points(vertices):
cdef list rays = [vector(ZZ, list(v)) for v in vertices]
if not rays:
return ()
cdef Vector_integer_dense origin = rays.pop()
cdef VectorClass origin = rays.pop()
origin.set_immutable()
if not rays:
return (origin,)
translate_points(rays, origin)

# Find equation Ax<=b that cuts out simplex from parallelotope
cdef Matrix_integer_dense Rt = matrix(ZZ, rays)
cdef Matrix_integer_dense R = Rt.transpose()
cdef MatrixClass Rt = matrix(ZZ, rays)
cdef MatrixClass R = Rt.transpose()
cdef int nrays = len(rays)
cdef Integer b
M = FreeModule(ZZ, nrays)
Expand All @@ -335,7 +329,7 @@ cpdef tuple simplex_points(vertices):
return points


cdef translate_points(v_list, Vector_integer_dense delta):
cdef translate_points(v_list, VectorClass delta):
r"""
Add ``delta`` to each vector in ``v_list``.
"""
Expand Down Expand Up @@ -568,7 +562,7 @@ cpdef rectangular_box_points(list box_min, list box_max,
return loop_over_rectangular_box_points(box_min, box_max, inequalities, d, count_only)
cdef list points = []
cdef Vector_integer_dense v = vector(ZZ, d)
cdef VectorClass v = vector(ZZ, d)
if not return_saturated:
for p in loop_over_rectangular_box_points(box_min, box_max, inequalities, d, count_only):
# v = vector(ZZ, perm_action(orig_perm, p)) # too slow
Expand Down
18 changes: 18 additions & 0 deletions src/sage/geometry/integral_points.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
try:
from .integral_points_integer_dense import (
parallelotope_points,
ray_matrix_normal_form,
loop_over_parallelotope_points,
simplex_points,
rectangular_box_points,
print_cache
)
except ImportError:
from .integral_points_generic_dense import (
parallelotope_points,
ray_matrix_normal_form,
loop_over_parallelotope_points,
simplex_points,
rectangular_box_points,
print_cache
)
6 changes: 6 additions & 0 deletions src/sage/geometry/integral_points_generic_dense.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#cython: wraparound=False, boundscheck=False

from sage.modules.vector_integer_dense cimport Vector_integer_dense as VectorClass
from sage.matrix.matrix_dense cimport Matrix_dense as MatrixClass

include "integral_points.pxi"
6 changes: 6 additions & 0 deletions src/sage/geometry/integral_points_integer_dense.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#cython: wraparound=False, boundscheck=False

from sage.modules.vector_integer_dense cimport Vector_integer_dense as VectorClass
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense as MatrixClass

include "integral_points.pxi"
2 changes: 1 addition & 1 deletion src/sage/matrix/matrix_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation):
else:
return matrix_integer_sparse.Matrix_integer_sparse

if R is sage.rings.real_double.RDF or R is sage.rings.complex_double.CDF:
if isinstance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)):
from . import matrix_double_sparse
return matrix_double_sparse.Matrix_double_sparse

Expand Down

0 comments on commit 9a8b269

Please sign in to comment.