@@ -1,5 +1,4 @@ | |||||
# file GENERATED by distutils, do NOT edit | # file GENERATED by distutils, do NOT edit | ||||
README | |||||
setup.py | setup.py | ||||
./src/permanent.c | ./src/permanent.c | ||||
permanent/__init__.py | permanent/__init__.py | ||||
@@ -0,0 +1 @@ | |||||
numpy |
@@ -3,19 +3,20 @@ | |||||
from distutils.core import setup, Extension | from distutils.core import setup, Extension | ||||
import numpy | import numpy | ||||
setup(name = "permanent", | |||||
version = "0.1.3", | |||||
description = "Calculates the permanent of a Numpy matrix", | |||||
author = "Pete Shadbolt", | |||||
author_email = "pete.shadbolt@gmail.com", | |||||
maintainer = "pete.shadbolt@gmail.com", | |||||
url = "https://github.com/peteshadbolt/permanent", | |||||
packages = ["permanent"], | |||||
ext_modules = [ | |||||
Extension( | |||||
'permanent.permanent', ['./src/permanent.c'], | |||||
extra_compile_args=["-Ofast", "-march=native"], | |||||
include_dirs=[numpy.get_include()]), | |||||
], | |||||
setup( | |||||
name="permanent", | |||||
version="0.1.3", | |||||
description="Calculates the permanent of a Numpy matrix", | |||||
author="Pete Shadbolt", | |||||
author_email="hello@peteshadbolt.co.uk", | |||||
maintainer="hello@peteshadbolt.co.uk", | |||||
url="https://github.com/peteshadbolt/permanent", | |||||
packages=["permanent"], | |||||
setup_requires=["numpy"], | |||||
ext_modules=[ | |||||
Extension( | |||||
'permanent.permanent', ['./src/permanent.c'], | |||||
extra_compile_args=["-Ofast", "-march=native"], | |||||
include_dirs=[numpy.get_include()]), | |||||
], | |||||
) | ) |
@@ -14,12 +14,32 @@ static PyMethodDef methods[] = { | |||||
{ NULL, NULL, 0, NULL } // Sentinel | { NULL, NULL, 0, NULL } // Sentinel | ||||
}; | }; | ||||
// Module initialization | |||||
#if PY_MAJOR_VERSION >= 3 | |||||
static struct PyModuleDef cModPyDem = | |||||
{ | |||||
PyModuleDef_HEAD_INIT, | |||||
"permanent", "Computes the permanent of a numpy using the most appropriate method available", | |||||
-1, | |||||
methods | |||||
}; | |||||
PyMODINIT_FUNC | |||||
PyInit_permanent(void) | |||||
{ | |||||
import_array(); | |||||
return PyModule_Create(&cModPyDem); | |||||
} | |||||
#else | |||||
PyMODINIT_FUNC initpermanent(void) { | PyMODINIT_FUNC initpermanent(void) { | ||||
(void) Py_InitModule("permanent", methods); | (void) Py_InitModule("permanent", methods); | ||||
import_array(); | import_array(); | ||||
} | } | ||||
#endif | |||||
// Ryser's algorithm | // Ryser's algorithm | ||||
static npy_complex128 ryser(PyArrayObject *submatrix) { | static npy_complex128 ryser(PyArrayObject *submatrix) { | ||||
int n = (int) PyArray_DIM(submatrix, 0); | int n = (int) PyArray_DIM(submatrix, 0); | ||||
@@ -0,0 +1,27 @@ | |||||
import numpy as np | |||||
from permanent.permanent import permanent | |||||
import pytest | |||||
def test_permanent(): | |||||
""" Test that basic functions work right """ | |||||
m = np.eye(10, dtype=complex) | |||||
assert permanent(m) == 1 | |||||
m = np.zeros((10, 10), dtype=complex) | |||||
assert permanent(m) == 0 | |||||
def test_floaty(): | |||||
""" More tests using a precomputed permanent """ | |||||
np.random.seed(1234) | |||||
m = np.random.uniform(0, 1, 16) + 1j * np.random.uniform(0, 1, 16) | |||||
m = m.reshape(4, 4) | |||||
p = permanent(m) | |||||
assert np.allclose(p, -8.766131870776363 + 1.072095650303524j) | |||||
def test_error(): | |||||
""" Should raise a TypeError as we are using the wrong dtype """ | |||||
with pytest.raises(TypeError): | |||||
m = np.eye(10, dtype=float) | |||||
permanent(m) |
@@ -0,0 +1,9 @@ | |||||
[tox] | |||||
envlist = py27, py36 | |||||
[testenv] | |||||
deps= | |||||
-r requirements.txt | |||||
pytest | |||||
pytest-mock | |||||
commands=pytest {posargs} |