From 47ce93cb292ad5eb431be1d62d6f825da9ab644e Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Mon, 10 Nov 2014 23:39:12 +0000 Subject: [PATCH] Better --- src/permanent.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/permanent.c b/src/permanent.c index 47e1094..db5c9e6 100644 --- a/src/permanent.c +++ b/src/permanent.c @@ -13,36 +13,32 @@ static const npy_complex128 complex_zero = {.real=0, .imag=0}; static const npy_complex128 complex_one = {.real=1, .imag=0}; static void complex_inc(npy_complex128 a, npy_complex128 b) { a.real+=b.real; a.imag+=b.imag;} -static npy_complex128 complex_mult(npy_complex128 a, npy_complex128 b) { +static npy_complex128 complex_prod(npy_complex128 a, npy_complex128 b) { npy_complex128 x; x.real = a.real*b.real+a.imag*b.imag; x.imag = a.real*b.imag+a.imag*b.real; return x; } -// Boilerplate: Forward function declaration, method list, module initialization -static PyObject *permanent(PyObject *self, PyObject *args); -static PyMethodDef methods[] = { +// Boilerplate +static PyObject *permanent(PyObject *self, PyObject *args); // Forward function declaration +static PyMethodDef methods[] = { // Method list { "permanent", permanent, METH_VARARGS, "Compute the permanent"}, { NULL, NULL, 0, NULL } /* Sentinel */ }; -PyMODINIT_FUNC initpermanent(void) { +PyMODINIT_FUNC initpermanent(void) { // Module initialization (void) Py_InitModule("permanent", methods); import_array(); } -// The parity -/*static int parity(int x) { return 0; }*/ - -// Ryser's algorithm takes exponential time -// This just calculates the sum +// Ryser's algorithm static npy_complex128 perm_ryser(PyArrayObject *submatrix) { int n = (int) PyArray_DIM(submatrix, 0); int i = 0; int z = 0; int y = 0; npy_complex128 prod; npy_complex128 perm = complex_zero; npy_complex128 sum = complex_zero; - int exp=1 << n; //TODO: use a shift operator + int exp = 1 << n; // Iterate over exponentially many index strings for (i=0; i 0) { complex_inc(sum, SM(z,y)); } } - prod = complex_mult(prod, sum); + prod = complex_prod(prod, sum); } - /*complex_add(perm, parity(i) * prod);*/ + if (i%2 == 0) {prod.real*=-1; prod.imag*=-1;} complex_inc(perm, prod); } - /*return c_prod((pow(-1,n)), perm); #TODO power is fucked*/ + if (i%2 == 0) {perm.real*=-1; perm.imag*=-1;} return perm; } -// This is basically a wrapper which chooses the optimal permanent function +// This is a wrapper which chooses the optimal permanent function static PyObject *permanent(PyObject *self, PyObject *args) { - // Parse input + // Parse the input PyArrayObject *submatrix; if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &submatrix)) {return NULL;} + // Compute the permanent npy_complex128 p = perm_ryser(submatrix); return PyComplex_FromDoubles(p.real, p.imag); }