'Evaluates the Ripley K estimator for a given set of values ``radii``.
Parameters
data : 2D array
Set of observed points in as a n by 2 array which will be used to
estimate Ripley\'s K function.
radii : 1D array
Set of distances in which Ripley\'s K estimator will be evaluated.
Usually, it\'s common to consider max(radii) < (area/2)**0.5.
mode : str
Keyword which indicates the method for edge effects correction.
Available methods are \'none\', \'translation\', \'ohser\', \'var-width\',
and \'ripley\'.
* \'none\'
this method does not take into account any edge effects
whatsoever.
* \'translation\'
computes the intersection of rectangular areas centered at
the given points provided the upper bounds of the
dimensions of the rectangular area of study. It assumes that
all the points lie in a bounded rectangular region satisfying
x_min < x_i < x_max; y_min < y_i < y_max. A detailed
description of this method can be found on ref [4].
* \'ohser\'
this method uses the isotropized set covariance function of
the window of study as a weigth to correct for
edge-effects. A detailed description of this method can be
found on ref [4].
* \'var-width\'
this method considers the distance of each observed point to
the nearest boundary of the study window as a factor to
account for edge-effects. See [3] for a brief description of
this method.
* \'ripley\'
this method is known as Ripley\'s edge-corrected estimator.
The weight for edge-correction is a function of the
proportions of circumferences centered at each data point
which crosses another data point of interest. See [3] for
a detailed description of this method.
Returns
ripley : 1D array
Ripley\'s K function estimator evaluated at ``radii``.'

def evaluate(self, data, radii, mode=u'none'):

    data = np.asarray(data)
    if (not (data.shape[1] == 2)):
        raise ValueError(u'data    must    be    an    n    by    2    array,    where    n    is    the    number    of    observed    points.')
    npts = len(data)
    ripley = np.zeros(len(radii))
    if (mode == u'none'):
        diff = self._pairwise_diffs(data)
        distances = np.hypot(diff[:, 0], diff[:, 1])
        for r in range(len(radii)):
            ripley[r] = (distances < radii[r]).sum()
        ripley = (((self.area * 2.0) * ripley) / (npts * (npts - 1)))
    elif (mode == u'translation'):
        diff = self._pairwise_diffs(data)
        distances = np.hypot(diff[:, 0], diff[:, 1])
        intersec_area = (((self.x_max - self.x_min) - diff[:, 0]) * ((self.y_max - self.y_min) - diff[:, 1]))
        for r in range(len(radii)):
            dist_indicator = (distances < radii[r])
            ripley[r] = ((1 / intersec_area) * dist_indicator).sum()
        ripley = ((((self.area ** 2) / (npts * (npts - 1))) * 2) * ripley)
    elif (mode == u'ohser'):
        diff = self._pairwise_diffs(data)
        distances = np.hypot(diff[:, 0], diff[:, 1])
        a = self.area
        b = max(((self.y_max - self.y_min) / (self.x_max - self.x_min)), ((self.x_max - self.x_min) / (self.y_max - self.y_min)))
        x = (distances / math.sqrt((a / b)))
        u = np.sqrt((((x * x) - 1) * (x > 1)))
        v = np.sqrt(((((x * x) - (b ** 2)) * (x < math.sqrt(((b ** 2) + 1)))) * (x > b)))
        c1 = ((np.pi - ((2 * x) * (1 + (1 / b)))) + ((x * x) / b))
        c2 = (((2 * np.arcsin(((1 / x) * (x > 1)))) - (1 / b)) - (2 * (x - u)))
        c3 = (((((2 * np.arcsin(((((b - (u * v)) / (x * x)) * (x > b)) * (x < math.sqrt(((b ** 2) + 1)))))) + (2 * u)) + ((2 * v) / b)) - b) - ((1 + (x * x)) / b))
        cov_func = ((a / np.pi) * ((((c1 * (x >= 0)) * (x <= 1)) + ((c2 * (x > 1)) * (x <= b))) + ((c3 * (b < x)) * (x < math.sqrt(((b ** 2) + 1))))))
        for r in range(len(radii)):
            dist_indicator = (distances < radii[r])
            ripley[r] = ((1 / cov_func) * dist_indicator).sum()
        ripley = ((((self.area ** 2) / (npts * (npts - 1))) * 2) * ripley)
    elif (mode == u'var-width'):
        lt_dist = np.minimum(np.minimum((self.x_max - data[:, 0]), (self.y_max - data[:, 1])), np.minimum((data[:, 0] - self.x_min), (data[:, 1] - self.y_min)))
        for r in range(len(radii)):
            for i in range(npts):
                for j in range(npts):
                    if (i != j):
                        diff = abs((data[i] - data[j]))
                        dist = math.sqrt((diff * diff).sum())
                        if ((dist < radii[r]) and (lt_dist[i] > radii[r])):
                            ripley[r] = (ripley[r] + 1)
            lt_dist_sum = (lt_dist > radii[r]).sum()
            if (not (lt_dist_sum == 0)):
                ripley[r] = (ripley[r] / lt_dist_sum)
        ripley = ((self.area * ripley) / npts)
    elif (mode == u'ripley'):
        hor_dist = np.zeros(shape=((npts * (npts - 1)) // 2), dtype=np.double)
        ver_dist = np.zeros(shape=((npts * (npts - 1)) // 2), dtype=np.double)
        for k in range((npts - 1)):
            min_hor_dist = min((self.x_max - data[k][0]), (data[k][0] - self.x_min))
            min_ver_dist = min((self.y_max - data[k][1]), (data[k][1] - self.y_min))
            start = ((k * ((2 * (npts - 1)) - (k - 1))) // 2)
            end = (((k + 1) * ((2 * (npts - 1)) - k)) // 2)
            hor_dist[start:end] = (min_hor_dist * np.ones(((npts - 1) - k)))
            ver_dist[start:end] = (min_ver_dist * np.ones(((npts - 1) - k)))
        diff = self._pairwise_diffs(data)
        dist = np.hypot(diff[:, 0], diff[:, 1])
        dist_ind = (dist <= np.hypot(hor_dist, ver_dist))
        w1 = (1 - ((np.arccos((np.minimum(ver_dist, dist) / dist)) + np.arccos((np.minimum(hor_dist, dist) / dist))) / np.pi))
        w2 = ((3 / 4) - ((0.5 * (np.arccos(((ver_dist / dist) * (~ dist_ind))) + np.arccos(((hor_dist / dist) * (~ dist_ind))))) / np.pi))
        weight = ((dist_ind * w1) + ((~ dist_ind) * w2))
        for r in range(len(radii)):
            ripley[r] = ((dist < radii[r]) / weight).sum()
        ripley = (((self.area * 2.0) * ripley) / (npts * (npts - 1)))
    else:
        raise ValueError(u'mode    {}    is    not    implemented.'.format(mode))
    return ripley
