aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml58
-rw-r--r--MANIFEST.in1
-rw-r--r--README.rst10
-rw-r--r--gensvm/core.py2
-rw-r--r--gensvm/cython_wrapper/wrapper.pyx25
-rw-r--r--gensvm/gridsearch.py2
-rw-r--r--gensvm/sklearn_util.py15
-rw-r--r--gensvm/util.py13
-rw-r--r--poetry.lock250
-rw-r--r--pyproject.toml19
-rw-r--r--setup.py163
11 files changed, 230 insertions, 328 deletions
diff --git a/.travis.yml b/.travis.yml
index 78aa334..0950aa6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,20 +1,50 @@
-language: python
-python:
- - "3.6"
- - "2.7"
+# Travis CI configuration for GenSVM
-env:
- - CC="gcc"
+jobs:
+ include:
+ - language: python
+ dist: xenial
+ python: "3.7"
+ services:
+ - docker
+ before_install:
+ - sudo apt-get update
+ - sudo apt-get install -y libatlas-base-dev liblapack-dev liblapacke-dev;
+ env:
+ - CC="gcc"
+ - PYTHON="python3"
+ - PIP="pip3"
+ - CIBW_BEFORE_BUILD="yum install -y atlas-devel lapack-devel && pip install numpy Cython"
+
+ - os: osx
+ osx_image: xcode11.3
+ language: generic
+ before_install:
+ - brew update
+ - brew install openblas
+ env:
+ - CC="gcc"
+ - CFLAGS="-fcommon" # avoids build errors on OSx
+ - PYTHON="python3"
+ - PIP="pip3"
+ - CIBW_BEFORE_BUILD="pip install numpy Cython"
-before_install:
- - sudo apt-get update
- - sudo apt-get install -y libatlas-base-dev liblapack-dev liblapacke-dev
+env:
+ global:
+ # - No longer actively maintaining gensvm for Python 2.7
+ # - Skipping 3.5 for now because scikit-learn is not available as wheel
+ # anymore, and this breaks testing.
+ - CIBW_SKIP="cp27-* cp35-*"
+ # Run the unit tests on the wheels that are created
+ - CIBW_TEST_REQUIRES="numpy Cython"
+ - CIBW_TEST_COMMAND="python -VV && python -m unittest discover -f -s {project}/test"
install:
- - pip install --upgrade pip
- - pip install -U -r requirements.txt
- - pip install green Cython
- - python setup.py build_ext --inplace
+ - $PIP install numpy
+ - $PIP install -e .[dev]
+ - $PYTHON -m unittest discover -v -f -s ./test
script:
- - green -vv -f
+ - $PIP install cibuildwheel==1.0.0
+ - cibuildwheel --output-dir wheelhouse
+ - ls wheelhouse
diff --git a/MANIFEST.in b/MANIFEST.in
index 5f5f17a..b1a1c22 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -12,6 +12,7 @@ exclude src/gensvm/.gitignore
exclude .gitmodules
exclude .gitignore
exclude .travis.yml
+exclude pyproject.toml
exclude Makefile
recursive-exclude test_human *.py
recursive-exclude docs *
diff --git a/README.rst b/README.rst
index bcb72b3..9f53d0c 100644
--- a/README.rst
+++ b/README.rst
@@ -36,16 +36,12 @@ J.J. van den Burg <https://gertjanvandenburg.com>`_ and `Patrick J.F. Groenen
Installation
------------
-**Before** GenSVM can be installed, a working NumPy installation is required.
-Please see `the installation instructions for NumPy
-<https://docs.scipy.org/doc/numpy-1.13.0/user/install.html>`_, then install
-GenSVM using the instructions below.
-
-GenSVM can be easily installed through pip:
+**Before** GenSVM can be installed, a working NumPy installation is required,
+so GenSVM can be installed using the following command:
.. code:: bash
- pip install gensvm
+ pip install numpy && pip install gensvm
If you encounter any errors, please open an issue on `GitHub
<https://github.com/GjjvdBurg/PyGenSVM>`_.
diff --git a/gensvm/core.py b/gensvm/core.py
index bfd5d9a..45d59ad 100644
--- a/gensvm/core.py
+++ b/gensvm/core.py
@@ -16,9 +16,9 @@ from sklearn.exceptions import ConvergenceWarning, FitFailedWarning
from sklearn.preprocessing import LabelEncoder
from sklearn.utils import check_array, check_X_y, check_random_state
from sklearn.utils.multiclass import type_of_target
-from sklearn.utils.validation import check_is_fitted
from .cython_wrapper import wrapper
+from .util import check_is_fitted
def _fit_gensvm(
diff --git a/gensvm/cython_wrapper/wrapper.pyx b/gensvm/cython_wrapper/wrapper.pyx
index 009e70b..3a85e92 100644
--- a/gensvm/cython_wrapper/wrapper.pyx
+++ b/gensvm/cython_wrapper/wrapper.pyx
@@ -88,8 +88,7 @@ def train_wrap(
raise ValueError(error_repl)
# Do the actual training
- with nogil:
- gensvm_train(model, data, seed_model)
+ gensvm_train(model, data, seed_model)
# update the number of variables (this may have changed due to kernel)
n_var = get_m(model)
@@ -134,12 +133,11 @@ def predict_wrap(
# output vector
cdef np.ndarray[np.int_t, ndim=1, mode='c'] predictions
- predictions = np.empty((n_test_obs, ), dtype=np.int)
+ predictions = np.empty((n_test_obs, ), dtype=np.int_)
# do the prediction
- with nogil:
- gensvm_predict(X.data, V.data, n_test_obs, n_var, n_class,
- predictions.data)
+ gensvm_predict(X.data, V.data, n_test_obs, n_var, n_class,
+ predictions.data)
return predictions
@@ -174,10 +172,9 @@ def predict_kernels_wrap(
cdef np.ndarray[np.int_t, ndim=1, mode='c'] predictions
predictions = np.empty((n_obs_test, ), dtype=np.int)
- with nogil:
- gensvm_predict_kernels(Xtest.data, Xtrain.data, V.data, V_rows,
- V_cols, n_obs_train, n_obs_test, n_var, n_class, kernel_idx,
- gamma, coef, degree, kernel_eigen_cutoff, predictions.data)
+ gensvm_predict_kernels(Xtest.data, Xtrain.data, V.data, V_rows, V_cols,
+ n_obs_train, n_obs_test, n_var, n_class, kernel_idx, gamma, coef,
+ degree, kernel_eigen_cutoff, predictions.data)
return predictions
@@ -243,9 +240,7 @@ def grid_wrap(
set_queue(queue, n_tasks, tasks)
- with nogil:
- gensvm_train_q_helper(queue, cv_idx.data, store_predictions,
- verbosity)
+ gensvm_train_q_helper(queue, cv_idx.data, store_predictions, verbosity)
cdef np.ndarray[np.int_t, ndim=1, mode='c'] pred
cdef np.ndarray[np.double_t, ndim=1, mode='c'] dur
@@ -264,12 +259,12 @@ def grid_wrap(
results['params'].append(candidate_params[ID])
results['scores'].append(get_task_performance(tasks[ID]))
if store_predictions:
- pred = np.zeros((n_obs, ), dtype=np.int)
+ pred = np.zeros((n_obs, ), dtype=np.int_)
copy_task_predictions(tasks[ID], pred.data, n_obs)
results['predictions'].append(pred.copy())
dur = np.zeros((n_folds, ), dtype=np.double)
copy_task_durations(tasks[ID], dur.data, n_folds)
- results['durations'].append(dur.copy())
+ results['durations'].append(dur)
gensvm_free_queue(queue)
free_data(data)
diff --git a/gensvm/gridsearch.py b/gensvm/gridsearch.py
index b27a347..22125a4 100644
--- a/gensvm/gridsearch.py
+++ b/gensvm/gridsearch.py
@@ -116,7 +116,7 @@ def _wrap_score(y_pred, y_true, scorers, is_multimetric):
results["score"] = np.nan
else:
estimator = _MockEstimator(y_pred)
- results = _score(estimator, None, y_true, scorers, is_multimetric)
+ results = _score(estimator, None, y_true, scorers)
score_time = time.time() - start_time
return results, score_time
diff --git a/gensvm/sklearn_util.py b/gensvm/sklearn_util.py
index 182f257..eb8ceb6 100644
--- a/gensvm/sklearn_util.py
+++ b/gensvm/sklearn_util.py
@@ -89,7 +89,9 @@ def _skl_format_cv_results(
score_time,
) = zip(*out)
else:
- (test_score_dicts, test_sample_counts, fit_time, score_time) = zip(*out)
+ (test_score_dicts, test_sample_counts, fit_time, score_time) = zip(
+ *out
+ )
# test_score_dicts and train_score dicts are lists of dictionaries and
# we make them into dict of lists
@@ -160,7 +162,9 @@ def _skl_format_cv_results(
)
if return_train_score:
_store(
- "train_%s" % scorer_name, train_scores[scorer_name], splits=True
+ "train_%s" % scorer_name,
+ train_scores[scorer_name],
+ splits=True,
)
return results
@@ -207,7 +211,12 @@ def _skl_check_is_fitted(estimator, method_name, refit):
"attribute" % (type(estimator).__name__, method_name)
)
else:
- check_is_fitted(estimator, "best_estimator_")
+ if not hasattr(estimator, "best_estimator_"):
+ raise NotFittedError(
+ "This %s instance is not fitted yet. Call "
+ "'fit' with appropriate arguments before using this "
+ "estimator." % type(estimator).__name__
+ )
def _skl_grid_score(X, y, scorer_, best_estimator_, refit, multimetric_):
diff --git a/gensvm/util.py b/gensvm/util.py
index 046f3be..40d0eb1 100644
--- a/gensvm/util.py
+++ b/gensvm/util.py
@@ -8,6 +8,7 @@ Utility functions for GenSVM
import numpy as np
+from sklearn.exceptions import NotFittedError
def get_ranks(a):
"""
@@ -37,3 +38,15 @@ def get_ranks(a):
ranks[~np.isnan(orig)] = count[dense - 1] + 1
ranks[np.isnan(orig)] = np.max(ranks) + 1
return list(ranks)
+
+
+def check_is_fitted(estimator, attribute):
+ msg = (
+ "This %(name)s instance is not fitted yet. Call 'fit' "
+ "with appropriate arguments before using this estimator."
+ )
+ if not hasattr(estimator, "fit"):
+ raise TypeError("%s is not an estimator instance" % (estimator))
+
+ if not hasattr(estimator, attribute):
+ raise NotFittedError(msg % {"name": type(estimator).__name__})
diff --git a/poetry.lock b/poetry.lock
deleted file mode 100644
index 91337ff..0000000
--- a/poetry.lock
+++ /dev/null
@@ -1,250 +0,0 @@
-[[package]]
-category = "dev"
-description = "A configurable sidebar-enabled Sphinx theme"
-name = "alabaster"
-optional = false
-python-versions = "*"
-version = "0.7.12"
-
-[[package]]
-category = "dev"
-description = "Internationalization utilities"
-name = "babel"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-version = "2.7.0"
-
-[package.dependencies]
-pytz = ">=2015.7"
-
-[[package]]
-category = "dev"
-description = "Python package for providing Mozilla's CA Bundle."
-name = "certifi"
-optional = false
-python-versions = "*"
-version = "2019.3.9"
-
-[[package]]
-category = "dev"
-description = "Universal encoding detector for Python 2 and 3"
-name = "chardet"
-optional = false
-python-versions = "*"
-version = "3.0.4"
-
-[[package]]
-category = "dev"
-description = "Cross-platform colored terminal text."
-marker = "sys_platform == \"win32\""
-name = "colorama"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-version = "0.4.1"
-
-[[package]]
-category = "dev"
-description = "Docutils -- Python Documentation Utilities"
-name = "docutils"
-optional = false
-python-versions = "*"
-version = "0.14"
-
-[[package]]
-category = "dev"
-description = "Internationalized Domain Names in Applications (IDNA)"
-name = "idna"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-version = "2.8"
-
-[[package]]
-category = "dev"
-description = "Getting image size from png/jpeg/jpeg2000/gif file"
-name = "imagesize"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-version = "1.1.0"
-
-[[package]]
-category = "dev"
-description = "A small but fast and easy to use stand-alone template engine written in pure python."
-name = "jinja2"
-optional = false
-python-versions = "*"
-version = "2.10.1"
-
-[package.dependencies]
-MarkupSafe = ">=0.23"
-
-[[package]]
-category = "main"
-description = "Lightweight pipelining: using Python functions as pipeline jobs."
-name = "joblib"
-optional = false
-python-versions = "*"
-version = "0.13.2"
-
-[[package]]
-category = "dev"
-description = "Safely add untrusted strings to HTML/XML markup."
-name = "markupsafe"
-optional = false
-python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
-version = "1.1.1"
-
-[[package]]
-category = "main"
-description = "NumPy is the fundamental package for array computing with Python."
-name = "numpy"
-optional = false
-python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
-version = "1.16.4"
-
-[[package]]
-category = "dev"
-description = "Pygments is a syntax highlighting package written in Python."
-name = "pygments"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-version = "2.4.2"
-
-[[package]]
-category = "dev"
-description = "World timezone definitions, modern and historical"
-name = "pytz"
-optional = false
-python-versions = "*"
-version = "2019.1"
-
-[[package]]
-category = "dev"
-description = "Python HTTP for Humans."
-name = "requests"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-version = "2.22.0"
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-chardet = ">=3.0.2,<3.1.0"
-idna = ">=2.5,<2.9"
-urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
-
-[[package]]
-category = "main"
-description = "A set of python modules for machine learning and data mining"
-name = "scikit-learn"
-optional = false
-python-versions = ">=3.5"
-version = "0.21.2"
-
-[package.dependencies]
-joblib = ">=0.11"
-numpy = ">=1.11.0"
-scipy = ">=0.17.0"
-
-[[package]]
-category = "main"
-description = "SciPy: Scientific Library for Python"
-name = "scipy"
-optional = false
-python-versions = ">=3.5"
-version = "1.3.0"
-
-[package.dependencies]
-numpy = ">=1.13.3"
-
-[[package]]
-category = "dev"
-description = "Python 2 and 3 compatibility utilities"
-name = "six"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*"
-version = "1.12.0"
-
-[[package]]
-category = "dev"
-description = "This package provides 16 stemmer algorithms (15 + Poerter English stemmer) generated from Snowball algorithms."
-name = "snowballstemmer"
-optional = false
-python-versions = "*"
-version = "1.2.1"
-
-[[package]]
-category = "dev"
-description = "Python documentation generator"
-name = "sphinx"
-optional = false
-python-versions = "*"
-version = "1.6.5"
-
-[package.dependencies]
-Jinja2 = ">=2.3"
-Pygments = ">=2.0"
-alabaster = ">=0.7,<0.8"
-babel = ">=1.3,<2.0 || >2.0"
-colorama = ">=0.3.5"
-docutils = ">=0.11"
-imagesize = "*"
-requests = ">=2.0.0"
-setuptools = "*"
-six = ">=1.5"
-snowballstemmer = ">=1.1"
-sphinxcontrib-websupport = "*"
-
-[[package]]
-category = "dev"
-description = "Read the Docs theme for Sphinx"
-name = "sphinx-rtd-theme"
-optional = false
-python-versions = "*"
-version = "0.4.3"
-
-[package.dependencies]
-sphinx = "*"
-
-[[package]]
-category = "dev"
-description = "Sphinx API for Web Apps"
-name = "sphinxcontrib-websupport"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-version = "1.1.2"
-
-[[package]]
-category = "dev"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-name = "urllib3"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4"
-version = "1.25.3"
-
-[metadata]
-content-hash = "28c38fca95c1a9663d1048eb9cffd5dcc8c73d85e4c79b0649aa7e550bdf0a09"
-python-versions = "^3.7"
-
-[metadata.hashes]
-alabaster = ["446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", "a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"]
-babel = ["af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab", "e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"]
-certifi = ["59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", "b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"]
-chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"]
-colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"]
-docutils = ["02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6", "51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274", "7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"]
-idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"]
-imagesize = ["3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8", "f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"]
-jinja2 = ["065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"]
-joblib = ["21e0c34a69ad7fde4f2b1f3402290e9ec46f545f15f1541c582edfe05d87b63a", "315d6b19643ec4afd4c41c671f9f2d65ea9d787da093487a81ead7b0bac94524"]
-markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"]
-numpy = ["0778076e764e146d3078b17c24c4d89e0ecd4ac5401beff8e1c87879043a0633", "141c7102f20abe6cf0d54c4ced8d565b86df4d3077ba2343b61a6db996cefec7", "14270a1ee8917d11e7753fb54fc7ffd1934f4d529235beec0b275e2ccf00333b", "27e11c7a8ec9d5838bc59f809bfa86efc8a4fd02e58960fa9c49d998e14332d5", "2a04dda79606f3d2f760384c38ccd3d5b9bb79d4c8126b67aff5eb09a253763e", "3c26010c1b51e1224a3ca6b8df807de6e95128b0908c7e34f190e7775455b0ca", "52c40f1a4262c896420c6ea1c6fda62cf67070e3947e3307f5562bd783a90336", "6e4f8d9e8aa79321657079b9ac03f3cf3fd067bf31c1cca4f56d49543f4356a5", "7242be12a58fec245ee9734e625964b97cf7e3f2f7d016603f9e56660ce479c7", "7dc253b542bfd4b4eb88d9dbae4ca079e7bf2e2afd819ee18891a43db66c60c7", "94f5bd885f67bbb25c82d80184abbf7ce4f6c3c3a41fbaa4182f034bba803e69", "a89e188daa119ffa0d03ce5123dee3f8ffd5115c896c2a9d4f0dbb3d8b95bfa3", "ad3399da9b0ca36e2f24de72f67ab2854a62e623274607e37e0ce5f5d5fa9166", "b0348be89275fd1d4c44ffa39530c41a21062f52299b1e3ee7d1c61f060044b8", "b5554368e4ede1856121b0dfa35ce71768102e4aa55e526cb8de7f374ff78722", "cbddc56b2502d3f87fda4f98d948eb5b11f36ff3902e17cb6cc44727f2200525", "d79f18f41751725c56eceab2a886f021d70fd70a6188fd386e29a045945ffc10", "dc2ca26a19ab32dc475dbad9dfe723d3a64c835f4c23f625c2b6566ca32b9f29", "dd9bcd4f294eb0633bb33d1a74febdd2b9018b8b8ed325f861fffcd2c7660bb8", "e8baab1bc7c9152715844f1faca6744f2416929de10d7639ed49555a85549f52", "ec31fe12668af687b99acf1567399632a7c47b0e17cfb9ae47c098644ef36797", "f12b4f7e2d8f9da3141564e6737d79016fe5336cc92de6814eba579744f65b0a", "f58ac38d5ca045a377b3b377c84df8175ab992c970a53332fa8ac2373df44ff7"]
-pygments = ["71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", "881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"]
-pytz = ["303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", "d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"]
-requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"]
-scikit-learn = ["051c53f9e900b0e9eccff2391f5317d1673d72e842bcbcd3e5d0b132459086ed", "0aafc312a55ebf58073151b9308761a5fcfa45b7f7730cea4b1f066f824c72db", "185d88ee4955cd68d7ff57356d1dd99cfc2de4b6aa5e5d679cafbc9df54716ff", "195465c39daded4f3ef8759291ffde81365486d4293e63dd9e32de0f569ecbbf", "4a6398500d035a4402476a2e3ae9f65a7a3f1b366ec6a7f6dd45c289f72dc954", "56f14e98632fb9237e7d005c6d8e346d01fa67f7b92f5f5d57a0bd06c741f9f6", "77092513dd780e12affde46a6394b52947db3fc00cf1d8c1c8eede52b37591d1", "7d2cdfe16b1ae6f9a1760b69be27c2004a84fc362984f930df135c847c47b765", "82c3450fc375f27e3529fa05fec627c9fc75915e05fcd55de43f193b3aa907af", "a5fba00d9037b62b0e0906f64efe9e4a754e556bc091cc12f84bc81655b4a414", "acba6bf5928e415b6296799a7aa069b66254c9440bce88ed2e5915865a317093", "b474f00d2533f18761fb17fb0950b27e72baf0796176247b5a7cf0ee369790ee", "ca45e0def97f73a828cee417174fafa0ab35a41f8bdca4424120a29c5589c548", "f09e544a6756afbd9d31e1d8ddfde5a2c9c17f6d4274104c988fceb611e2d5c5", "f979bb85cbfd9ed4d54709d86ab8893b316726abd1c9ab04abe7e6414b71b753", "fb4c7a2294447515fffec33c1f5eedbe942e9be56edb8c6619607e7882531d40"]
-scipy = ["03b1e0775edbe6a4c64effb05fff2ce1429b76d29d754aa5ee2d848b60033351", "09d008237baabf52a5d4f5a6fcf9b3c03408f3f61a69c404472a16861a73917e", "10325f0ffac2400b1ec09537b7e403419dcd25d9fee602a44e8a32119af9079e", "1db9f964ed9c52dc5bd6127f0dd90ac89791daa690a5665cc01eae185912e1ba", "409846be9d6bdcbd78b9e5afe2f64b2da5a923dd7c1cd0615ce589489533fdbb", "4907040f62b91c2e170359c3d36c000af783f0fa1516a83d6c1517cde0af5340", "6c0543f2fdd38dee631fb023c0f31c284a532d205590b393d72009c14847f5b1", "826b9f5fbb7f908a13aa1efd4b7321e36992f5868d5d8311c7b40cf9b11ca0e7", "a7695a378c2ce402405ea37b12c7a338a8755e081869bd6b95858893ceb617ae", "a84c31e8409b420c3ca57fd30c7589378d6fdc8d155d866a7f8e6e80dec6fd06", "adadeeae5500de0da2b9e8dd478520d0a9945b577b2198f2462555e68f58e7ef", "b283a76a83fe463c9587a2c88003f800e08c3929dfbeba833b78260f9c209785", "c19a7389ab3cd712058a8c3c9ffd8d27a57f3d84b9c91a931f542682bb3d269d", "c3bb4bd2aca82fb498247deeac12265921fe231502a6bc6edea3ee7fe6c40a7a", "c5ea60ece0c0c1c849025bfc541b60a6751b491b6f11dd9ef37ab5b8c9041921", "db61a640ca20f237317d27bc658c1fc54c7581ff7f6502d112922dc285bdabee"]
-six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"]
-snowballstemmer = ["919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128", "9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89"]
-sphinx = ["c6de5dbdbb7a0d7d2757f4389cc00e8f6eb3c49e1772378967a12cfcf2cfe098", "fdf77f4f30d84a314c797d67fe7d1b46665e6c48a25699d7bf0610e05a2221d4"]
-sphinx-rtd-theme = ["00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4", "728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a"]
-sphinxcontrib-websupport = ["1501befb0fdf1d1c29a800fdbf4ef5dc5369377300ddbdd16d2cd40e54c6eefc", "e02f717baf02d0b6c3dd62cf81232ffca4c9d5c331e03766982e3ff9f1d2bc3f"]
-urllib3 = ["b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", "dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"]
diff --git a/pyproject.toml b/pyproject.toml
deleted file mode 100644
index 1668a61..0000000
--- a/pyproject.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[tool.poetry]
-name = "gensvm"
-version = "0.2.4"
-description = "Python package for the GenSVM classifier"
-authors = ["Gertjan van den Burg <gertjanvandenburg@gmail.com>"]
-license = "GPL-2.0+"
-
-[tool.poetry.dependencies]
-python = "^3.7"
-scikit-learn = "^0.21.2"
-numpy = "^1.16"
-
-[tool.poetry.dev-dependencies]
-Sphinx = "=1.6.5"
-sphinx_rtd_theme = "^0.4.3"
-
-[build-system]
-requires = ["poetry>=0.12"]
-build-backend = "poetry.masonry.api"
diff --git a/setup.py b/setup.py
index ff6b0a9..5738dc4 100644
--- a/setup.py
+++ b/setup.py
@@ -3,6 +3,32 @@
import os
import re
+import sys
+
+# Package meta-data
+AUTHOR = "Gertjan van den Burg"
+DESCRIPTION = "Generalized Multiclass Support Vector Machines"
+EMAIL = "gertjanvandenburg@gmail.com"
+LICENSE = "GPLv2"
+LICENSE_TROVE = (
+ "License :: OSI Approved :: GNU General Public License v2 (GPLv2)"
+)
+NAME = "gensvm"
+REQUIRES_PYTHON = ">=2.7"
+URL = "https://github.com/GjjvdBurg/PyGenSVM"
+VERSION = None
+
+REQUIRED = ["scikit-learn", "numpy"]
+
+docs_require = ["Sphinx==1.6.5", "sphinx_rtd_theme>=0.4.3"]
+test_require = []
+dev_require = ["Cython"]
+
+EXTRAS = {
+ "docs": docs_require,
+ "tests": test_require,
+ "dev": docs_require + test_require + dev_require,
+}
# Set this to True to enable building extensions using Cython. Set it to FalseĀ·
# to build extensions from the C file (that was previously generated usingĀ·
@@ -10,7 +36,7 @@ import re
# the C file.
USE_CYTHON = "auto"
-# If we are in a release, we always never use Cython directly
+# If we are in a release, we never use Cython directly
IS_RELEASE = os.path.exists("PKG-INFO")
if IS_RELEASE:
USE_CYTHON = False
@@ -25,15 +51,30 @@ if USE_CYTHON:
else:
raise
-# Try to load setuptools, so that NumPy's distutils module that we use to
-# provide the setup() function below comes from the setuptools package. If it
-# fails, it'll use distutils' version, which doesn't support installing
+# Try to load setuptools, so that NumPy's distutils module that we use to
+# provide the setup() function below comes from the setuptools package. If it
+# fails, it'll use distutils' version, which doesn't support installing
# dependencies.
try:
- import setuptools
+ import setuptools
except ImportError:
- print("Warning: setuptools not found. You may have to install GenSVM's dependencies manually.")
+ print(
+ "Warning: setuptools not found. You may have to install GenSVM's dependencies manually."
+ )
+
+def on_cibw_win():
+ return (
+ os.environ.get("CIBUILDWHEEL", "0") == "1"
+ and os.environ.get("TRAVIS_OS_NAME", "none") == "windows"
+ )
+
+
+def on_cibw_mac():
+ return (
+ os.environ.get("CIBUILDWHEEL", "0") == "1"
+ and os.environ.get("TRAVIS_OS_NAME", "none") == "osx"
+ )
def _skl_get_blas_info():
@@ -73,7 +114,7 @@ def _skl_get_blas_info():
from numpy.distutils.system_info import get_info
def atlas_not_found(blas_info_):
- def_macros = blas_info.get("define_macros", [])
+ def_macros = blas_info_.get("define_macros", [])
for x in def_macros:
if x[0] == "NO_ATLAS_INFO":
# if x[1] != 1 we should have lapack
@@ -85,13 +126,59 @@ def _skl_get_blas_info():
return True
return False
- blas_info = get_info("blas_opt", 0)
+ if on_cibw_win():
+ blas_info = get_info("blas_opt", notfound_action=0)
+ blas_info = {
+ "define_macros": [("NO_ATLAS_INFO", 1), ("HAVE_CBLAS", None)],
+ "library_dirs": [
+ os.sep.join(
+ [
+ "C:",
+ "cibw",
+ "openblas",
+ "OpenBLAS.0.2.14.1",
+ "lib",
+ "native",
+ "lib",
+ ]
+ )
+ ],
+ "include_dirs": [
+ os.sep.join(
+ [
+ "C:",
+ "cibw",
+ "openblas",
+ "OpenBLAS.0.2.14.1",
+ "lib",
+ "native",
+ "include",
+ ]
+ )
+ ],
+ "language": "c",
+ }
+ return ["libopenblas"], blas_info
+
+ blas_info = get_info("blas_opt", notfound_action=2)
if (not blas_info) or atlas_not_found(blas_info):
cblas_libs = ["cblas"]
blas_info.pop("libraries", None)
else:
cblas_libs = blas_info.pop("libraries", [])
+ if os.environ.get("TRAVIS_OS_NAME", "none") == "osx":
+ libdir = blas_info.get("library_dirs", [])
+ libdir = libdir[0] if libdir else None
+ if libdir:
+ base = os.path.split(libdir)[0]
+ blas_info["include_dirs"] = [os.path.join(base, "include")]
+
+ if on_cibw_mac():
+ blas_info["include_dirs"] = [
+ "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Versions/Current/Headers/"
+ ]
+
return cblas_libs, blas_info
@@ -100,7 +187,7 @@ def get_lapack_info():
from numpy.distutils.system_info import get_info
def atlas_not_found(lapack_info_):
- def_macros = lapack_info.get("define_macros", [])
+ def_macros = lapack_info_.get("define_macros", [])
for x in def_macros:
if x[0] == "NO_ATLAS_INFO":
return True
@@ -109,9 +196,45 @@ def get_lapack_info():
return True
return False
- lapack_info = get_info("lapack_opt", 0)
+ if on_cibw_win():
+ lapack_info = get_info("lapack_opt", notfound_action=0)
+ lapack_info = {
+ "define_macros": [("NO_ATLAS_INFO", 1), ("HAVE_CBLAS", None)],
+ "library_dirs": [
+ os.sep.join(
+ [
+ "C:",
+ "cibw",
+ "openblas",
+ "OpenBLAS.0.2.14.1",
+ "lib",
+ "native",
+ "lib",
+ ]
+ )
+ ],
+ "include_dirs": [
+ os.sep.join(
+ [
+ "C:",
+ "cibw",
+ "openblas",
+ "OpenBLAS.0.2.14.1",
+ "lib",
+ "native",
+ "include",
+ ]
+ )
+ ],
+ "language": "c",
+ }
+ print("***\nDefined lapack info: %r" % lapack_info)
+ return ["libopenblas"], lapack_info
+
+ lapack_info = get_info("lapack_opt", notfound_action=2)
+
if (not lapack_info) or atlas_not_found(lapack_info):
- # This is a guess, but seems to work in practice. Need more systems to
+ # This is a guess, but seems to work in practice. Need more systems to
# test this fully.
lapack_libs = ["lapack"]
lapack_info.pop("libraries", None)
@@ -182,6 +305,9 @@ def read(fname):
def check_requirements():
numpy_instructions = (
+ "\n"
+ "GenSVM Installation Error:"
+ "\n"
"Numerical Python (NumPy) is not installed on your "
"system. This package is required for GenSVM. Please install "
"NumPy using the instructions available here: "
@@ -206,14 +332,15 @@ if __name__ == "__main__":
attr = configuration().todict()
attr["version"] = version
- attr["description"] = "Python package for the GenSVM classifier"
+ attr["description"] = DESCRIPTION
attr["long_description"] = read("README.rst")
- attr["packages"] = ["gensvm"]
- attr["url"] = "https://github.com/GjjvdBurg/PyGenSVM"
- attr["author"] = "G.J.J. van den Burg"
- attr["author_email"] = "gertjanvandenburg@gmail.com"
- attr["license"] = "GPL v2"
- attr["install_requires"] = ["scikit-learn", "numpy"]
+ attr["packages"] = [NAME]
+ attr["url"] = URL
+ attr["author"] = AUTHOR
+ attr["author_email"] = EMAIL
+ attr["license"] = LICENSE
+ attr["install_requires"] = REQUIRED
+ attr["extras_require"] = EXTRAS
from numpy.distutils.core import setup