Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions KDEpy/BaseKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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
Expand Down
12 changes: 8 additions & 4 deletions KDEpy/FFTKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""
Module for the FFTKDE.
"""
from __future__ import division, absolute_import, print_function

import numbers
import warnings
import numpy as np
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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)

Expand Down
8 changes: 5 additions & 3 deletions KDEpy/NaiveKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""
Module for the NaiveKDE.
"""
from __future__ import division, absolute_import, print_function

import numbers
import itertools
import numpy as np
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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])
Expand Down
8 changes: 5 additions & 3 deletions KDEpy/TreeKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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])

Expand Down
2 changes: 2 additions & 0 deletions KDEpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/binning.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/bw_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""
Functions for bandwidth selection.
"""
from __future__ import absolute_import, division, print_function

import numpy as np
import scipy
import warnings
Expand Down
11 changes: 9 additions & 2 deletions KDEpy/kernel_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_BaseKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_FFTKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_NaiveKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_TreeKDE.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_binning.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_estimator_vs_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_kernel_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/tests/test_sorted_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions KDEpy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""
Module for utility functions.
"""
from __future__ import absolute_import, division, print_function

import numpy as np
import numbers

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__))

Expand Down