blob: 8a0cba67df27f20e22f008509f20bbc607ddf015 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#!/usr/bin/python
2
3"""Wrapper around libcdd, a polytope manipulation library."""
4
5__author__ = 'Austin Schuh (austin.linux@gmail.com)'
6
7import ctypes
Brian Silvermandc3748d2014-03-30 12:41:52 -07008import sys
brians343bc112013-02-10 01:53:46 +00009
10# Wrapper around PyFile_AsFile so that we can print out the error messages.
11# Set the arg type and return types of the function call.
12class FILE(ctypes.Structure):
13 pass
14
15ctypes.pythonapi.PyFile_AsFile.argtypes = [ctypes.py_object]
16ctypes.pythonapi.PyFile_AsFile.restype = ctypes.POINTER(FILE)
17
18# Load and init libcdd. libcdd is a C library that implements algorithm to
19# manipulate half space and vertex representations of polytopes.
20# Unfortunately, the library was compiled with C++ even though it has a lot of C
21# code in it, so all the symbol names are mangled. Ug.
22libcdd = ctypes.cdll.LoadLibrary('libcdd.so')
Austin Schuhbf9d6502015-09-11 23:59:15 -070023libcdd.dd_set_global_constants()
brians343bc112013-02-10 01:53:46 +000024
25# The variable type mytype that libcdd defines (double[1])
26# See http://docs.python.org/2/library/ctypes.html#arrays for the documentation
27# explaining why ctypes.c_double * 1 => double[1]
28# libcdd defines mytype to various things so it can essentially template its
29# functions. What a weird library.
30mytype = ctypes.c_double * 1
31
32
33# Forward declaration for the polyhedra data structure.
34class dd_polyhedradata(ctypes.Structure):
35 pass
36
37
38# Definition of dd_matrixdata
39class dd_matrixdata(ctypes.Structure):
40 _fields_ = [
41 ("rowsize", ctypes.c_long),
42 ("linset", ctypes.POINTER(ctypes.c_ulong)),
43 ("colsize", ctypes.c_long),
44 ("representation", ctypes.c_int),
45 ("numbtype", ctypes.c_int),
46 ("matrix", ctypes.POINTER(ctypes.POINTER(mytype))),
47 ("objective", ctypes.c_int),
48 ("rowvec", ctypes.POINTER(mytype)),
49 ]
50
51# Define the input and output types for a bunch of libcdd functions.
Austin Schuhbf9d6502015-09-11 23:59:15 -070052libcdd.dd_CreateMatrix.restype = ctypes.POINTER(dd_matrixdata)
53libcdd.ddd_get_d.argtypes = [mytype]
54libcdd.ddd_get_d.restype = ctypes.c_double
brians343bc112013-02-10 01:53:46 +000055
Austin Schuhbf9d6502015-09-11 23:59:15 -070056libcdd.dd_CopyGenerators.argtypes = [
brians343bc112013-02-10 01:53:46 +000057 ctypes.POINTER(dd_polyhedradata)
58]
Austin Schuhbf9d6502015-09-11 23:59:15 -070059libcdd.dd_CopyGenerators.restype = ctypes.POINTER(dd_matrixdata)
brians343bc112013-02-10 01:53:46 +000060
Austin Schuhbf9d6502015-09-11 23:59:15 -070061libcdd.dd_DDMatrix2Poly.argtypes = [
brians343bc112013-02-10 01:53:46 +000062 ctypes.POINTER(dd_matrixdata),
63 ctypes.POINTER(ctypes.c_int)
64]
Austin Schuhbf9d6502015-09-11 23:59:15 -070065libcdd.dd_DDMatrix2Poly.restype = (
brians343bc112013-02-10 01:53:46 +000066 ctypes.POINTER(dd_polyhedradata))
67
Austin Schuhbf9d6502015-09-11 23:59:15 -070068libcdd.dd_FreeMatrix.argtypes = [
brians343bc112013-02-10 01:53:46 +000069 ctypes.POINTER(dd_matrixdata)
70]
71
Austin Schuhbf9d6502015-09-11 23:59:15 -070072libcdd.dd_FreePolyhedra.argtypes = [
brians343bc112013-02-10 01:53:46 +000073 ctypes.POINTER(dd_polyhedradata)
74]
75
Austin Schuhbf9d6502015-09-11 23:59:15 -070076libcdd.ddd_set_d.argtypes = [
brians343bc112013-02-10 01:53:46 +000077 mytype,
78 ctypes.c_double
79]
80
81
82# Various enums.
83DD_INEQUALITY = 1
84DD_REAL = 1
85DD_NO_ERRORS = 17
86
87
88def dd_CreateMatrix(rows, cols):
Austin Schuhbf9d6502015-09-11 23:59:15 -070089 return libcdd.dd_CreateMatrix(ctypes.c_long(rows), ctypes.c_long(cols))
brians343bc112013-02-10 01:53:46 +000090
91
92def dd_set_d(mytype_address, double_value):
Austin Schuhbf9d6502015-09-11 23:59:15 -070093 libcdd.ddd_set_d(mytype_address, ctypes.c_double(double_value))
brians343bc112013-02-10 01:53:46 +000094
95
96def dd_CopyGenerators(polyhedraptr):
Austin Schuhbf9d6502015-09-11 23:59:15 -070097 return libcdd.dd_CopyGenerators(polyhedraptr)
brians343bc112013-02-10 01:53:46 +000098
99
100def dd_get_d(mytype_address):
Austin Schuhbf9d6502015-09-11 23:59:15 -0700101 return libcdd.ddd_get_d(mytype_address)
brians343bc112013-02-10 01:53:46 +0000102
103
104def dd_FreeMatrix(matrixptr):
Austin Schuhbf9d6502015-09-11 23:59:15 -0700105 libcdd.dd_FreeMatrix(matrixptr)
brians343bc112013-02-10 01:53:46 +0000106
107
108def dd_FreePolyhedra(polyhedraptr):
Austin Schuhbf9d6502015-09-11 23:59:15 -0700109 libcdd.dd_FreePolyhedra(polyhedraptr)
brians343bc112013-02-10 01:53:46 +0000110
111
112def dd_DDMatrix2Poly(matrixptr):
113 error = ctypes.c_int()
Austin Schuhbf9d6502015-09-11 23:59:15 -0700114 polyhedraptr = libcdd.dd_DDMatrix2Poly(matrixptr, ctypes.byref(error))
brians343bc112013-02-10 01:53:46 +0000115
116 # Return None on error.
117 # The error values are enums, so they aren't exposed.
Austin Schuhf69ef922013-10-07 23:21:12 -0700118 if error.value != DD_NO_ERRORS:
brians343bc112013-02-10 01:53:46 +0000119 # Dump out the errors to stderr
Austin Schuhbf9d6502015-09-11 23:59:15 -0700120 libcdd.dd_WriteErrorMessages(
brians343bc112013-02-10 01:53:46 +0000121 ctypes.pythonapi.PyFile_AsFile(ctypes.py_object(sys.stdout)),
122 error)
123 dd_FreePolyhedra(polyhedraptr)
124 return None
125 return polyhedraptr