예제 #1
0
    def __data(self) -> Tuple[dict, Tuple[int, int]]:
        cycles = self._model.runbead()
        if cycles is None:
            return self._DEFAULT_DATA

        items = list(cycles)
        if len(items) == 0 or not any(len(i) for _, i in items):
            return self.__data()

        if self._model.eventdetection.task is None:
            res, shape = self.__normal_data(items)
        else:
            res, shape = self.__event_data(items)

        tmp = np.array([i[-1] for i, _ in items], dtype='i4')
        res['cycle'] = (as_strided(tmp,
                                   shape=shape,
                                   strides=(tmp.strides[0], 0)).ravel())

        tmp = np.array(
            self.attrs(self._theme.raw).listpalette(
                shape[0], theme=self._model.themename))
        res['color'] = (as_strided(tmp,
                                   shape=shape,
                                   strides=(tmp.strides[0], 0)).ravel())

        assert all(len(i) == len(res['z']) for i in res.values())
        return res, shape
예제 #2
0
    def __call__(self, durations: np.ndarray, cycles: np.ndarray) -> np.ndarray:
        phase  = PHASE.measure-1
        first  = sum(durations[:phase])
        last   = first+durations[phase]
        mid    = int(self.closing*(last-first))+first
        rho    = (self.strandsize-cycles[:,first-1])/(mid-first+1)

        cycles[:,first:mid]  = np.outer(rho, np.arange(1, mid-first+1))
        cycles[:,first:mid] += as_strided(cycles[:,first-1].ravel(),
                                          shape   = cycles[:,first:mid].shape,
                                          strides = (cycles.strides[1], 0))
        cycles[:,mid:last]   = np.outer(-rho, np.arange(last-mid, 0, -1))
        cycles[:,mid:last]  += as_strided(cycles[:,last].ravel(),
                                          shape   = cycles[:,mid:last].shape,
                                          strides = (cycles.strides[1], 0))
예제 #3
0
    def __normal_data(items):
        size = max(len(i) for _, i in items)
        val = np.full((len(items), size), np.NaN, dtype='f4')
        for i, (_, j) in zip(val, items):
            i[:len(j)] = j

        tmp = np.arange(size, dtype='i4')
        time = as_strided(tmp, shape=val.shape, strides=(0, tmp.strides[0]))
        return dict(t=time.ravel(), z=val.ravel()), val.shape
예제 #4
0
    def _kernel_density_estimate(self, X, output_onlylogp=False, ):
        """
        Estimate density and relevant quantities for data points specified by X
        with kernel density estimation.

        Parameters
        ----------
        X : array
            2D array including multiple data points. Input to density estimation.
        output_onlylogp : bool
            If true, returns logp, else returns p, g, h, msu.

        Returns
        -------
        p : array
            1D array.  Unnormalized probability density. The probability density
            is not normalized due to numerical stability. Exact log probability
            density is returned if `output_onlylogp=True`.
        g : array, optional
            2D array. Gradient of the probability density function.
        h : array, optional
            3D array. Hessian of the probability density function.
        msu :
            2D array. Meanshift update based on the probability density function.
        """

        # the number of data points and the dimensionality
        n, d = self.data.shape

        # and evaluate the kernel at each distance
        D = cdist(self.data, X)

        # prevent numerical overflow due to large exponentials
        logc = -d * np.log(np.min(self.adaptive_bw)) - d / 2 * np.log(2 * np.pi)
        C = (self.adaptive_bw[:, np.newaxis] / np.min(self.adaptive_bw)) ** (-d) * \
            np.exp(-1 / 2. * (D / self.adaptive_bw[:, np.newaxis]) ** 2)

        if output_onlylogp:
            # return the kernel density estimate
            return np.log(np.mean(C, axis=0).T) + logc
        else:
            # gradient of p
            u = vdist(self.data, X)
            g = np.mean((C / (self.adaptive_bw[:, np.newaxis] ** 2)).T[:, :, np.newaxis] * u, axis=1)

            # hessian of p
            Z = np.eye(d)
            h = matrix_multiply(
                (C / (n * self.adaptive_bw[:, np.newaxis] ** 4)).T[:, np.newaxis, :] * u.transpose((0, 2, 1)), u) - \
                as_strided(Z, strides=(0, Z.strides[0], Z.strides[1]), shape=(C.shape[1], Z.shape[0], Z.shape[1])) * \
                (np.sum(C / (n * self.adaptive_bw[:, np.newaxis] ** 2), axis=0)[:, np.newaxis, np.newaxis])
            # for computation of msu = Cp * g
            Cp = 1. / np.mean(C / (self.adaptive_bw[:, np.newaxis] ** 2), axis=0)
            # return the kernel density estimate
            return np.mean(C, axis=0).T, g, h, Cp[:, np.newaxis] * g
예제 #5
0
def vdist(a, b):
    """
    This function is similar to cdist but returning vectors rather than norm of vectors
    implemented via virtual copies of a and b

    Parameters
    ----------
    a,b : np.ndarray
        2D arrays of size (M,D), (N,D) for which differences for all pairwise combinations
        of rows in the two arrays will be computed. The number of columns have to the same
        between a and b.

    Returns
    ----------
    numpy.array
        3D array of size (N, M, D), containing all pairwise differences of rows in a and b.
    """
    return as_strided(a, strides=(0, a.strides[0], a.strides[1]),
                      shape=(b.shape[0], a.shape[0], a.shape[1])) - \
           as_strided(b, strides=(b.strides[0], 0, b.strides[1]),
                      shape=(b.shape[0], a.shape[0], b.shape[1]))
예제 #6
0
    def __get(self, elem):
        if len(elem) <= 2:
            return np.NaN

        if len(elem) <= self.binsize:
            return np.median(elem)

        bsize = self.binsize
        binned = as_strided(elem,
                            shape=(len(elem) - bsize + 1, bsize),
                            strides=(elem.strides[0], ) * 2)
        return np.median(binned, axis=0)
def generalized_broadcast(arrays):
    """
    Broadcast X and Y, while ignoring the last axis of X and Y.

    If X.shape = xs + (i,)
    and Y.shape = ys + (j,)
    then the output arrays have shapes
    Xb.shape = zs + (i,)
    Yb.shape = zs + (j,)
    where zs is the shape of the broadcasting of xs and ys shaped arrays.

    :param arrays: a list of numpy arrays to be broadcasted while ignoring the last axis.
    :return: a list of arrays whose shapes have been broadcast
    """
    arrays1 = np.broadcast_arrays(*[A[..., 0] for A in arrays])
    shapes_b = [A1.shape + (A.shape[-1],) for A1, A in zip(arrays1, arrays)]
    strides_b = [A1.strides + (A.strides[-1],) for A1, A in zip(arrays1, arrays)]
    arrays_b = [as_strided(A, shape=shape_Ab, strides=strides_Ab)
                for A, shape_Ab, strides_Ab in zip(arrays, shapes_b, strides_b)]
    return arrays_b
예제 #8
0
def generalized_broadcast(arrays):
    """
    Broadcast X and Y, while ignoring the last axis of X and Y.

    If X.shape = xs + (i,)
    and Y.shape = ys + (j,)
    then the output arrays have shapes
    Xb.shape = zs + (i,)
    Yb.shape = zs + (j,)
    where zs is the shape of the broadcasting of xs and ys shaped arrays.

    :param arrays: a list of numpy arrays to be broadcasted while ignoring the last axis.
    :return: a list of arrays whose shapes have been broadcast
    """
    arrays1 = np.broadcast_arrays(*[A[..., 0] for A in arrays])
    shapes_b = [A1.shape + (A.shape[-1],) for A1, A in zip(arrays1, arrays)]
    strides_b = [A1.strides + (A.strides[-1],) for A1, A in zip(arrays1, arrays)]
    arrays_b = [as_strided(A, shape=shape_Ab, strides=strides_Ab)
                for A, shape_Ab, strides_Ab in zip(arrays, shapes_b, strides_b)]
    return arrays_b
예제 #9
0
    def _multilevel_kernel_density_estimate(self, X, output_onlylogp=False, normalized=True):
        """
        Estimate density and relevant quantities for data points specified by X
        with kernel density estimation and multi-level data representation.
        Data point-specific bandwidth (self.adaptive_bw) is not supported and self.bw
        is used instead.


        Parameters
        ----------
        X : array
            2D array. Input to density estimation.
        output_onlylogp : bool
            If true, returns logp, else returns p, g, h, msu.

        Returns
        -------
        p : array
            1D array.  Unnormalized probability density. The probability density
            is not normalized due to numerical stability. Exact log probability
            density is returned if `output_onlylogp=True`.
        g : array, optional
            2D array. Gradient of the probability density function.
        h : array, optional
            3D array. Hessian of the probability density function.
        msu :
            2D array. Meanshift update based on the probability density function.
        """

        # the number of data points and the dimensionality
        npgh = []
        for data in self.data:
            n, d = data.shape
            # and evaluate the kernel at each distance
            D = cdist(data, X)
            if normalized:
                # prevent numerical overflow due to large exponentials
                logc = -d * np.log(self.bw) - d / 2 * np.log(2 * np.pi)
            else:
                warnings.warn("Warning: use unnormalized probablity. This does not affect density ridge-related estimates.")
                logc = 0
            C = np.exp(-1 / 2. * (D / self.bw) ** 2)

            if output_onlylogp:
                # return the kernel density estimate
                npgh.append((n, np.log(np.mean(C, axis=0).T) + logc))
            else:
                # gradient of p
                u = vdist(data, X)
                g = np.mean((C / (self.bw ** 2)).T[:, :, np.newaxis] * u, axis=1)

                # hessian of p
                Z = np.eye(d)
                h = matrix_multiply((C / (n * self.bw ** 4)).T[:, np.newaxis, :] * u.transpose((0, 2, 1)), u) - \
                    as_strided(Z, strides=(0, Z.strides[0], Z.strides[1]), shape=(C.shape[1], Z.shape[0], Z.shape[1])) * \
                    (np.sum(C / (n * self.bw ** 2), axis=0)[:, np.newaxis, np.newaxis])
                Cp = 1. / np.mean(C / (self.bw ** 2), axis=0)
                npgh.append((n, np.mean(C, axis=0).T, g, h, Cp))

            if output_onlylogp:
                ns = np.asarray([n * 2 ** i for i, (n, _) in enumerate(npgh)])
                ws = ns / ns.sum()
                logps = [(logp + np.log(ws[i]))[np.newaxis, :] for i, (n, logp) in enumerate(npgh)]
                logps = np.vstack(logps)
                logps = logsumexp(logps, axis=0)

                return logps

            else:
                ns = np.asarray([n * 2 ** i for i, (n, _, _, _, _) in enumerate(npgh)])
                ws = ns / ns.sum()

                ps, gs, hs, cps = npgh[0][1:]
                ps = ps * ws[0]
                gs = gs * ws[0]
                hs = hs * ws[0]
                cps = cps * ws[0]
                for i, (n, p, g, h, cp) in enumerate(npgh[1:]):
                    ps = ps + p * ws[i]
                    gs = gs + g * ws[i]
                    hs = hs + h * ws[i]
                    cps = cps + cps * ws[i]

                return ps, gs, hs, cps[:, np.newaxis] * gs