1 | initial version |
Perhaps, you best shot would be using Normaliz either as a backend of a polyhedron, or directly via PyNormaliz. A sample code via MILP construction:
cone_generators = [vector(QQ,v) for v in [[1.1, 2.3], [3, 0.2]]] # we want elements be from exact field such as QQ
lattice_generators = [vector(QQ,v) for v in [[1, 0], [0.2, 0.3]]]
milp = MixedIntegerLinearProgram(solver='ppl') # ppl works over QQ
c = milp.new_variable(real=True,nonnegative=True)
n = milp.new_variable(integer=True)
Eq = sum(c[i]*v for i,v in enumerate(cone_generators)) - sum(n[i]*v for i,v in enumerate(lattice_generators))
for e in Eq: milp.add_constraint( e == 0 )
P = milp.polyhedron(backend='normaliz')
print( P.integral_points_generators() )
which prints:
(((0, 0, 0, 0),), ((0, 15, 43, 10), (2, 1, 2, 16), (30, 0, -13, 230)), ())
See docs for integral_points_generators() and this issue for mapping results to MILP variables. It may be more straightforward to use PyNormaliz.
2 | No.2 Revision |
Perhaps, you your best shot would be using Normaliz either as a backend of a polyhedron, Polyhedron()
, or directly via PyNormaliz.
A sample code via MILP construction:
cone_generators = [vector(QQ,v) for v in [[1.1, 2.3], [3, 0.2]]] # we want elements be from exact field such as QQ
lattice_generators = [vector(QQ,v) for v in [[1, 0], [0.2, 0.3]]]
milp = MixedIntegerLinearProgram(solver='ppl') # ppl works over QQ
c = milp.new_variable(real=True,nonnegative=True)
n = milp.new_variable(integer=True)
Eq = sum(c[i]*v for i,v in enumerate(cone_generators)) - sum(n[i]*v for i,v in enumerate(lattice_generators))
for e in Eq: milp.add_constraint( e == 0 )
P = milp.polyhedron(backend='normaliz')
print( P.integral_points_generators() )
which prints:
(((0, 0, 0, 0),), ((0, 15, 43, 10), (2, 1, 2, 16), (30, 0, -13, 230)), ())
See docs for integral_points_generators() and this issue for mapping results to MILP variables. It may be more straightforward to use PyNormaliz.
3 | No.3 Revision |
Perhaps, your best shot would be using Normaliz either as a backend of Polyhedron()
, or directly via PyNormaliz.
A sample code via MILP construction:
cone_generators = [vector(QQ,v) for v in [[1.1, 2.3], [3, 0.2]]] # we want elements be from exact field such as QQ
lattice_generators = [vector(QQ,v) for v in [[1, 0], [0.2, 0.3]]]
milp = MixedIntegerLinearProgram(solver='ppl') # ppl works over QQ
c = milp.new_variable(real=True,nonnegative=True)
n = milp.new_variable(integer=True)
Eq = sum(c[i]*v for i,v in enumerate(cone_generators)) - sum(n[i]*v for i,v in enumerate(lattice_generators))
for e in Eq: milp.add_constraint( e == 0 )
P = milp.polyhedron(backend='normaliz')
print( P.integral_points_generators() )
which prints:
(((0, 0, 0, 0),), ((0, 15, 43, 10), (2, 1, 2, 16), (30, 0, -13, 230)), ())
See docs for integral_points_generators() and this issue for mapping these results to MILP variables. variables c
and n
. It may be more straightforward to use PyNormaliz.PyNormaliz without MILP.
4 | No.4 Revision |
Perhaps, your best shot would be using Normaliz either as a backend of Polyhedron()
, or directly via PyNormaliz.
A sample code via MILP construction:
cone_generators = [vector(QQ,v) for v in [[1.1, 2.3], [3, 0.2]]] # we want elements be from exact field such as QQ
0.2]]]
lattice_generators = [vector(QQ,v) for v in [[1, 0], [0.2, 0.3]]]
L = len(lattice_generators)
def get_backend_index(mip_var):
return int(str(mip_var)[2:])
milp = MixedIntegerLinearProgram(solver='ppl') # ppl works over QQ
MixedIntegerLinearProgram(solver='ppl')
c = milp.new_variable(real=True,nonnegative=True)
n = milp.new_variable(integer=True)
Eq = sum(c[i]*v for i,v in enumerate(cone_generators)) - sum(n[i]*v for i,v in enumerate(lattice_generators))
for e in Eq: milp.add_constraint( e == 0 )
P = milp.polyhedron(backend='normaliz')
# computing projection on n-plane
V = [vector(v[get_backend_index(n[i])] for i in range(L)) for v in P.vertices()]
R = [vector(v[get_backend_index(n[i])] for i in range(L)) for v in P.rays()]
projP = Polyhedron(backend='normaliz', vertices=V, rays=R)
print( P.integral_points_generators() projP.integral_points_generators() )
which prints:
(((0, 0, 0, 0),), ((0, 15, 43, 10),
((-13, 230), (-10, 177), (-7, 124), (-4, 71), (-1, 18), (0, 1), (1, 1), (2, 1, 2, 16), 1), (3, 1), (4, 1), (17, 4), (30, 0, -13, 230)), 7), (43, 10)),
())
See docs for integral_points_generators() and this issue for mapping these results to MILP variables . It may be more straightforward to use PyNormaliz without MILP.c
and n