| @@ -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} | |||||