Introduction
Both PANDA and lrs (or, for that matter, also PORTA and cdd) are useful tools to solve vertex enumeration and convex hull problems, which are common tasks in computational geometry and quantum foundations. Apart from implementing different algorithms, they also differ in their input specifications, and when dealing with inequalities, PANDA is vastly more user-friendly than lrs. Take, for instance, this cube:
|
|
If we were to convert it to an lrs input file, we’d write
|
|
as lrs expects inequalities of the form $a_0 + a_1 x_1 + \ldots + a_{n-1} x_{n-1} \geq 0$. When writing larger polytopes by hand, this quickly becomes unreadable and error-prone, so I made a parser to convert a PANDA-like H-representation file to an lrs one.
File specifications
Any input to the parser should have a Names section with variables names separated by a blank space, an Inequalities section, and may optionally have Equations. Any constants must be on the RHS of any expression. Hence, the first snippet would be valid, and this one also would:
|
|
Calling panda2lrs.py on this input would readily output an lrs readable file, with each equation turned into two inequalities, and each inequality manipulated to what lrs expects. If you don’t care for implementation details and just wanna know how to use it, you can skip the next section and see the usage details at the end.
*Implementation details
From lrs’s user guide, we know that any H-representation input must have the structure
|
|
where each inequality is of the form $a_0 + a_1 x_1 + \ldots + a_{n-1} x_{n-1} \geq 0$. In order to convert, I first read the input file and put each segment in a list. I then store the index where each section (which are Names, Equations and Inequalities) start, and find out what variables are listed under Names.
|
|
Preprocessing done, I now read the equations one by one, and send them to my expression parser. The parser will then take the equality string and the NAMES
list, extract the coefficients from the expression as numbers (and put a $0$ for the missing terms), and return a list with them. This list has the same ordering as the NAMES
specification (see the whole script for the details on the parser function).
|
|
Note that lrs doesn’t support equalities, so I turn each input equality into two inequalities in the last line.
The following step is essentially the same, but now parsing the inequalities:
|
|
To wrap everything up, I concatenate these lists and format them in a way that lrs will understand by asking
|
|
All this done to the example from the last section will result in the lrs-ready output
|
|
Usage
You can find panda2lrs.py
in here. Given an input with the aforementioned specifications, running this is quite simple: call python panda2lrs.py input
to print the results to the screen, or python panda2lrs.py input output
to directly write to a file named output
(if a file with the same name already exists, it’ll be overwritten!). You can then feed output
to lrs and watch it search your vertices.
I still haven’t used it much, so there may be some bugs. Please let me know if you find any issues (: