blob: 6b81a4f1a64ae02e28fe28b775d3686fddd71fc3 [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')
23libcdd._Z23dd_set_global_constantsv()
24
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.
52libcdd._Z15dd_CreateMatrixll.restype = ctypes.POINTER(dd_matrixdata)
53libcdd._Z9ddd_get_dPd.argtypes = [mytype]
54libcdd._Z9ddd_get_dPd.restype = ctypes.c_double
55
56libcdd._Z17dd_CopyGeneratorsP16dd_polyhedradata.argtypes = [
57 ctypes.POINTER(dd_polyhedradata)
58]
59libcdd._Z17dd_CopyGeneratorsP16dd_polyhedradata.restype = ctypes.POINTER(dd_matrixdata)
60
61libcdd._Z16dd_DDMatrix2PolyP13dd_matrixdataP12dd_ErrorType.argtypes = [
62 ctypes.POINTER(dd_matrixdata),
63 ctypes.POINTER(ctypes.c_int)
64]
65libcdd._Z16dd_DDMatrix2PolyP13dd_matrixdataP12dd_ErrorType.restype = (
66 ctypes.POINTER(dd_polyhedradata))
67
68libcdd._Z13dd_FreeMatrixP13dd_matrixdata.argtypes = [
69 ctypes.POINTER(dd_matrixdata)
70]
71
72libcdd._Z16dd_FreePolyhedraP16dd_polyhedradata.argtypes = [
73 ctypes.POINTER(dd_polyhedradata)
74]
75
76libcdd._Z9ddd_set_dPdd.argtypes = [
77 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):
89 return libcdd._Z15dd_CreateMatrixll(
90 ctypes.c_long(rows),
91 ctypes.c_long(cols))
92
93
94def dd_set_d(mytype_address, double_value):
95 libcdd._Z9ddd_set_dPdd(mytype_address,
96 ctypes.c_double(double_value))
97
98
99def dd_CopyGenerators(polyhedraptr):
100 return libcdd._Z17dd_CopyGeneratorsP16dd_polyhedradata(polyhedraptr)
101
102
103def dd_get_d(mytype_address):
104 return libcdd._Z9ddd_get_dPd(mytype_address)
105
106
107def dd_FreeMatrix(matrixptr):
108 libcdd._Z13dd_FreeMatrixP13dd_matrixdata(matrixptr)
109
110
111def dd_FreePolyhedra(polyhedraptr):
112 libcdd._Z16dd_FreePolyhedraP16dd_polyhedradata(polyhedraptr)
113
114
115def dd_DDMatrix2Poly(matrixptr):
116 error = ctypes.c_int()
117 polyhedraptr = libcdd._Z16dd_DDMatrix2PolyP13dd_matrixdataP12dd_ErrorType(
118 matrixptr,
119 ctypes.byref(error))
120
121 # Return None on error.
122 # The error values are enums, so they aren't exposed.
Austin Schuhf69ef922013-10-07 23:21:12 -0700123 if error.value != DD_NO_ERRORS:
brians343bc112013-02-10 01:53:46 +0000124 # Dump out the errors to stderr
125 libcdd._Z21dd_WriteErrorMessagesP8_IO_FILE12dd_ErrorType(
126 ctypes.pythonapi.PyFile_AsFile(ctypes.py_object(sys.stdout)),
127 error)
128 dd_FreePolyhedra(polyhedraptr)
129 return None
130 return polyhedraptr