Source code for mgwr.kernels

```# GWR kernel function specifications

__author__ = "Taylor Oshan tayoshan@gmail.com"

import numpy as np
#adaptive specifications should be parameterized with nn-1 to match original gwr
#implementation. That is, pysal counts self neighbors with knn automatically.

#Soft dependency of numba's njit
try:
from numba import njit
except ImportError:

def njit(func):
return func

@njit
def local_cdist(coords_i, coords, spherical):
"""
Compute Haversine (spherical=True) or Euclidean (spherical=False) distance for a local kernel.
"""
if spherical:
dLat = np.radians(coords[:, 1] - coords_i[1])
dLon = np.radians(coords[:, 0] - coords_i[0])
a = np.sin(
dLat / 2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dLon / 2)**2
c = 2 * np.arcsin(np.sqrt(a))
R = 6371.0
return R * c
else:
return np.sqrt(np.sum((coords_i - coords)**2, axis=1))

[docs]class Kernel(object):
"""
GWR kernel function specifications.

"""

[docs]    def __init__(self, i, data, bw=None, fixed=True, function='triangular',
eps=1.0000001, ids=None, points=None, spherical=False):

if points is None:
self.dvec = local_cdist(data[i], data, spherical).reshape(-1)
else:
self.dvec = local_cdist(points[i], data, spherical).reshape(-1)

self.function = function.lower()

if fixed:
self.bandwidth = float(bw)
else:
self.bandwidth = np.partition(
self.dvec,
int(bw) - 1)[int(bw) - 1] * eps  #partial sort in O(n) Time

self.kernel = self._kernel_funcs(self.dvec / self.bandwidth)

if self.function == "bisquare":  #Truncate for bisquare
self.kernel[(self.dvec >= self.bandwidth)] = 0

def _kernel_funcs(self, zs):
# functions follow Anselin and Rey (2010) table 5.4
if self.function == 'triangular':
return 1 - zs
elif self.function == 'uniform':
return np.ones(zi.shape) * 0.5