diff --git a/KDEpy/BaseKDE.py b/KDEpy/BaseKDE.py index 48f2743..5ddeca2 100644 --- a/KDEpy/BaseKDE.py +++ b/KDEpy/BaseKDE.py @@ -3,16 +3,24 @@ """ Module for the BaseKDE class. """ +from __future__ import absolute_import, division, print_function + +import six import numbers import numpy as np -from abc import ABC, abstractmethod -from collections.abc import Sequence +from abc import ABCMeta, abstractmethod from KDEpy.kernel_funcs import _kernel_functions from KDEpy.bw_selection import _bw_methods from KDEpy.utils import autogrid +if six.PY3: + from collections.abc import Sequence +else: + from collections import Sequence + -class BaseKDE(ABC): +@six.add_metaclass(ABCMeta) +class BaseKDE: """ Abstract Base Class for every Kernel Density Estimator. @@ -31,7 +39,7 @@ class BaseKDE(ABC): _bw_methods = _bw_methods @abstractmethod - def __init__(self, kernel: str, bw: float): + def __init__(self, kernel, bw): """Initialize the kernel density estimator. The return type must be duplicated in the docstring to comply diff --git a/KDEpy/FFTKDE.py b/KDEpy/FFTKDE.py index d2d0dfa..3ecb4d2 100644 --- a/KDEpy/FFTKDE.py +++ b/KDEpy/FFTKDE.py @@ -3,6 +3,8 @@ """ Module for the FFTKDE. """ +from __future__ import division, absolute_import, print_function + import numbers import warnings import numpy as np @@ -69,7 +71,7 @@ class FFTKDE(BaseKDE): def __init__(self, kernel="gaussian", bw=1, norm=2): self.norm = norm - super().__init__(kernel, bw) + super(FFTKDE, self).__init__(kernel, bw) assert isinstance(self.norm, numbers.Number) and self.norm > 0 def fit(self, data, weights=None): @@ -99,7 +101,7 @@ def fit(self, data, weights=None): """ # Sets self.data - super().fit(data, weights) + super(FFTKDE, self).fit(data, weights) return self def evaluate(self, grid_points=None): @@ -131,7 +133,7 @@ def evaluate(self, grid_points=None): """ # This method sets self.grid_points and verifies it - super().evaluate(grid_points) + super(FFTKDE, self).evaluate(grid_points) # Extra verification for FFTKDE (checking the sorting property) if not grid_is_sorted(self.grid_points): @@ -186,7 +188,9 @@ def evaluate(self, grid_points=None): assert (dx * L <= real_bw).all() # Evaluate the kernel once - grids = [np.linspace(-dx * L, dx * L, int(L * 2 + 1)) for (dx, L) in zip(dx, L)] + grids = [ + np.linspace(-dx * Li, dx * Li, int(Li * 2 + 1)) for (dx, Li) in zip(dx, L) + ] kernel_grid = cartesian(grids) kernel_weights = self.kernel(kernel_grid, bw=self.bw, norm=self.norm) diff --git a/KDEpy/NaiveKDE.py b/KDEpy/NaiveKDE.py index 0cad600..2c15128 100644 --- a/KDEpy/NaiveKDE.py +++ b/KDEpy/NaiveKDE.py @@ -3,6 +3,8 @@ """ Module for the NaiveKDE. """ +from __future__ import division, absolute_import, print_function + import numbers import itertools import numpy as np @@ -50,7 +52,7 @@ class NaiveKDE(BaseKDE): """ def __init__(self, kernel="gaussian", bw=1, norm=2): - super().__init__(kernel, bw) + super(NaiveKDE, self).__init__(kernel, bw) self.norm = norm def fit(self, data, weights=None): @@ -80,7 +82,7 @@ def fit(self, data, weights=None): >>> x, y = kde() """ # Sets self.data - super().fit(data, weights) + super(NaiveKDE, self).fit(data, weights) return self def evaluate(self, grid_points=None): @@ -113,7 +115,7 @@ def evaluate(self, grid_points=None): # This method sets self.grid points and verifies it # NaiveKDE does not convert the bw to a scalar, since a vector is # allowed too. - super().evaluate(grid_points, bw_to_scalar=False) + super(NaiveKDE, self).evaluate(grid_points, bw_to_scalar=False) # Create zeros on the grid points evaluated = np.zeros(self.grid_points.shape[0]) diff --git a/KDEpy/TreeKDE.py b/KDEpy/TreeKDE.py index 2aa3fc6..f14b77c 100644 --- a/KDEpy/TreeKDE.py +++ b/KDEpy/TreeKDE.py @@ -3,6 +3,8 @@ """ Module for the TreeKDE. """ +from __future__ import division, absolute_import, print_function + from scipy.spatial import cKDTree import numbers import numpy as np @@ -60,7 +62,7 @@ class TreeKDE(BaseKDE): """ def __init__(self, kernel="gaussian", bw=1, norm=2.0): - super().__init__(kernel, bw) + super(TreeKDE, self).__init__(kernel, bw) self.norm = norm def fit(self, data, weights=None): @@ -90,7 +92,7 @@ def fit(self, data, weights=None): >>> x, y = kde() """ # Sets self.data - super().fit(data, weights) + super(TreeKDE, self).fit(data, weights) return self def evaluate(self, grid_points=None, eps=10e-4): @@ -126,7 +128,7 @@ def evaluate(self, grid_points=None, eps=10e-4): """ # This method sets self.grid points and verifies it - super().evaluate(grid_points) + super(TreeKDE, self).evaluate(grid_points) evaluated = np.zeros(self.grid_points.shape[0]) diff --git a/KDEpy/__init__.py b/KDEpy/__init__.py index 717127a..bfaf5f6 100644 --- a/KDEpy/__init__.py +++ b/KDEpy/__init__.py @@ -2,6 +2,8 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + from KDEpy.NaiveKDE import NaiveKDE from KDEpy.TreeKDE import TreeKDE from KDEpy.FFTKDE import FFTKDE diff --git a/KDEpy/binning.py b/KDEpy/binning.py index 8c37fcc..eb36316 100644 --- a/KDEpy/binning.py +++ b/KDEpy/binning.py @@ -29,6 +29,8 @@ Journal of Computational and Graphical Statistics 3, no. 1 (March 1, 1994). https://doi.org/10.1080/10618600.1994.10474629. """ +from __future__ import division, absolute_import, print_function + import numpy as np import itertools import functools diff --git a/KDEpy/bw_selection.py b/KDEpy/bw_selection.py index 681c00b..d6a70e8 100644 --- a/KDEpy/bw_selection.py +++ b/KDEpy/bw_selection.py @@ -3,6 +3,8 @@ """ Functions for bandwidth selection. """ +from __future__ import absolute_import, division, print_function + import numpy as np import scipy import warnings diff --git a/KDEpy/kernel_funcs.py b/KDEpy/kernel_funcs.py index 06fea4b..8583c85 100644 --- a/KDEpy/kernel_funcs.py +++ b/KDEpy/kernel_funcs.py @@ -5,14 +5,21 @@ is everywhere non-negative and whose integral evalutes to unity. Every kernel function takes an `x` of shape (obs, dims) and returns a y of shape (obs, 1). """ +from __future__ import division, absolute_import, print_function import numpy as np -import collections.abc import numbers import functools from scipy.special import gamma, factorial2 from scipy.stats import norm from scipy.optimize import brentq +import six + +if six.PY3: + import collections.abc as collections_abc +else: + import collections as collections_abc + # In R, the following are implemented: # "gaussian", "rectangular", "triangular", "epanechnikov", @@ -223,7 +230,7 @@ def sigmoid(x, dims=1): return 1 / (np.pi * np.cosh(x)) -class Kernel(collections.abc.Callable): +class Kernel(collections_abc.Callable): def __init__(self, function, var=1, support=3): """ Initialize a new kernel function. diff --git a/KDEpy/tests/test_BaseKDE.py b/KDEpy/tests/test_BaseKDE.py index e77f375..4ab1a9c 100644 --- a/KDEpy/tests/test_BaseKDE.py +++ b/KDEpy/tests/test_BaseKDE.py @@ -4,6 +4,8 @@ API tests. Since BaseKDE is an abstract class, the testing is done using the naiveKDE class instead. The tests here are related to input types. """ +from __future__ import absolute_import, division, print_function + import numpy as np from KDEpy.NaiveKDE import NaiveKDE import itertools diff --git a/KDEpy/tests/test_FFTKDE.py b/KDEpy/tests/test_FFTKDE.py index 41ab8b4..e50bf12 100644 --- a/KDEpy/tests/test_FFTKDE.py +++ b/KDEpy/tests/test_FFTKDE.py @@ -3,6 +3,8 @@ """ Tests for the FFTKDE. """ +from __future__ import absolute_import, division, print_function + import numpy as np from KDEpy.FFTKDE import FFTKDE from KDEpy.NaiveKDE import NaiveKDE diff --git a/KDEpy/tests/test_NaiveKDE.py b/KDEpy/tests/test_NaiveKDE.py index b71c3d2..6a97bc8 100644 --- a/KDEpy/tests/test_NaiveKDE.py +++ b/KDEpy/tests/test_NaiveKDE.py @@ -4,6 +4,8 @@ Tests for the NaiveKDE. The NaiveKDE is tested against various properties, and in turn more advanced implementations are tested against the NaiveKDE. """ +from __future__ import absolute_import, division, print_function + import numpy as np from KDEpy.NaiveKDE import NaiveKDE import itertools diff --git a/KDEpy/tests/test_TreeKDE.py b/KDEpy/tests/test_TreeKDE.py index dc2a92c..7f9c986 100644 --- a/KDEpy/tests/test_TreeKDE.py +++ b/KDEpy/tests/test_TreeKDE.py @@ -3,6 +3,8 @@ """ Tests for the TreeKDE. """ +from __future__ import absolute_import, division, print_function + import numpy as np from KDEpy.TreeKDE import TreeKDE import itertools diff --git a/KDEpy/tests/test_api.py b/KDEpy/tests/test_api.py index 05e3a69..5c40b32 100644 --- a/KDEpy/tests/test_api.py +++ b/KDEpy/tests/test_api.py @@ -5,6 +5,8 @@ be equal for every implementation. Therefore it's important to have unit tests for the API. """ +from __future__ import absolute_import, division, print_function + import numpy as np from KDEpy.FFTKDE import FFTKDE from KDEpy.NaiveKDE import NaiveKDE diff --git a/KDEpy/tests/test_binning.py b/KDEpy/tests/test_binning.py index 6c4c845..530dede 100644 --- a/KDEpy/tests/test_binning.py +++ b/KDEpy/tests/test_binning.py @@ -3,6 +3,8 @@ """ Tests for binning functions. """ +from __future__ import division, absolute_import, print_function + import pytest import numpy as np from KDEpy.utils import autogrid diff --git a/KDEpy/tests/test_estimator_vs_estimator.py b/KDEpy/tests/test_estimator_vs_estimator.py index ecf878f..b56fe98 100644 --- a/KDEpy/tests/test_estimator_vs_estimator.py +++ b/KDEpy/tests/test_estimator_vs_estimator.py @@ -3,6 +3,8 @@ """ Test the implemented estimators against each other on simple data sets. """ +from __future__ import absolute_import, division, print_function + import numpy as np from KDEpy.NaiveKDE import NaiveKDE from KDEpy.TreeKDE import TreeKDE diff --git a/KDEpy/tests/test_kernel_funcs.py b/KDEpy/tests/test_kernel_funcs.py index 1ba8dc8..3ba2ada 100644 --- a/KDEpy/tests/test_kernel_funcs.py +++ b/KDEpy/tests/test_kernel_funcs.py @@ -4,6 +4,8 @@ Test the kernel functions K. Every kernel function is a radial basis function, i.e. it's a composition of a norm and a function defined on positive reals. """ +from __future__ import absolute_import, division, print_function + import numpy as np import scipy from scipy.integrate import quad diff --git a/KDEpy/tests/test_sorted_grid.py b/KDEpy/tests/test_sorted_grid.py index 65e405f..4b61d17 100644 --- a/KDEpy/tests/test_sorted_grid.py +++ b/KDEpy/tests/test_sorted_grid.py @@ -3,6 +3,8 @@ """ Tests for verifying that grids obeys the sorting properties required for linear binning. """ +from __future__ import absolute_import, division, print_function + import pytest import numpy as np from KDEpy.binning import grid_is_sorted # Imported from .pyx to binning.py, then here diff --git a/KDEpy/utils.py b/KDEpy/utils.py index c27e782..dfea68b 100644 --- a/KDEpy/utils.py +++ b/KDEpy/utils.py @@ -3,6 +3,8 @@ """ Module for utility functions. """ +from __future__ import absolute_import, division, print_function + import numpy as np import numbers diff --git a/setup.py b/setup.py index 2198d8b..14864dc 100644 --- a/setup.py +++ b/setup.py @@ -10,6 +10,7 @@ from setuptools import Extension, setup import os import re +from io import open HERE = os.path.abspath(os.path.dirname(__file__))