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
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))
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
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
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]))
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
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