Ask Your Question

Revision history [back]

click to hide/show revision 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.

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.

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.

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 c and n. It may be more straightforward to use PyNormaliz without MILP.