def _analysis_non_streaming(self, x): """ STFT analysis for non-streaming case in which we expect [(num_frames-1)*hop+num_samples] samples """ ## ----- STRIDED WAY new_strides = (x.strides[0], self.hop * x.strides[0]) new_shape = (self.num_samples, self.num_frames) if self.num_channels > 1: for c in range(self.num_channels): y = _as_strided(x[:, c], shape=new_shape, strides=new_strides) y = np.concatenate((np.zeros((self.zf, self.num_frames)), y, np.zeros((self.zb, self.num_frames)))) if self.num_frames == 1: self.X[:, c] = self.dft_frames.analysis(y[:, 0]).T else: self.X[:, :, c] = self.dft_frames.analysis(y).T else: y = _as_strided(x, shape=new_shape, strides=new_strides) y = np.concatenate((np.zeros((self.zf, self.num_frames)), y, np.zeros((self.zb, self.num_frames)))) if self.num_frames == 1: self.X[:] = self.dft_frames.analysis(y[:, 0]).T else: self.X[:] = self.dft_frames.analysis(y).T
def block_toeplitz_alt(c_tup, r_tup=None, sparse=False): c = create_object_array(c_tup) if r_tup is None: try: r = c.conjugate() except AttributeError: r = c else: r = create_object_array(r_tup) # # Form a 1D array containing a reversed c followed by r[1:] that could be # # strided to give us toeplitz matrix. vals = np.concatenate((c[::-1], r[1:])) out_shp = c.shape[0], r.shape[0] n = vals.strides[0] strided = _as_strided(vals[len(c) - 1:], shape=out_shp, strides=(-n, n)) np_toep = np.block(strided.tolist()) if sparse: if all(isinstance(block, scs.csr_matrix) for block in np_toep.flat): v_stacked = [ scs.bmat(np.atleast_2d(col).T).tocsc() for col in np_toep.T ] return scs.bmat(np.atleast_2d(v_stacked)).tocsr() else: h_stacked = [ scs.bmat(np.atleast_2d(row)).tocsr() for row in np_toep ] return scs.bmat(np.atleast_2d(h_stacked).T).tocsc() else: return np_toep
def stft(x, L, hop, transform=np.fft.fft, win=None, zp_back=0, zp_front=0): ''' Parameters ---------- x: input signal L: frame size hop: shift size between frames transform: the transform routine to apply (default FFT) win: the window to apply (default None) zp_back: zero padding to apply at the end of the frame zp_front: zero padding to apply at the beginning of the frame Returns ------- The STFT of x ''' warnings.warn("The function pyroomacoustics.stft is deprecated and will disappear soon. It will be replaced by the pyroomacoustics.transform.STFT object.", DeprecationWarning) # the transform size N = L + zp_back + zp_front # window needs to be same size as transform if (win is not None and len(win) != N): print('Window length need to be equal to frame length + zero padding.') sys.exit(-1) # reshape new_strides = (hop * x.strides[0], x.strides[0]) new_shape = ((len(x) - L) // hop + 1, L) y = _as_strided(x, shape=new_shape, strides=new_strides) # add the zero-padding y = np.concatenate( ( np.zeros( (y.shape[0], zp_front), dtype=x.dtype), y, np.zeros( (y.shape[0], zp_back), dtype=x.dtype) ), axis=1) # apply window if needed if (win is not None): y = win.astype(x.dtype) * y # transform along rows Z = transform(y, axis=1) # apply transform return Z
def block_toeplitz(c_tup, r_tup=None, sparse=False): """ Based on scipy.linalg.toeplitz method but applied in a block fashion. """ try: c = np.array(c_tup) except ValueError: c = create_object_array(c_tup) if r_tup is None: if np.issubdtype(c.dtype, np.number): r = c.conjugate() else: r = c else: try: r = np.array(r_tup) except ValueError: r = create_object_array(r_tup) c = _atleast_3d_col(c) r = _atleast_3d_col(r) # # Form a array containing a reversed c followed by r[1:] that could be strided to give us a toeplitz matrix. try: vals = np.concatenate((c[::-1], r[1:])) except ValueError as ve: raise ValueError( "Incompatible dimensions in c_tup or between c_tup and r_tup - " + ve.args[0]) stride_shp = (c.shape[0], c.shape[1], r.shape[0], r.shape[2]) out_shp = (c.shape[0] * c.shape[1], r.shape[0] * r.shape[2]) n, m, k = vals.strides strided = np.ascontiguousarray( _as_strided(vals[c.shape[0] - 1:], shape=stride_shp, strides=(-n, m, n, k))) np_toeplitz = strided.reshape(out_shp) if sparse: if np_toeplitz.dtype != np.object_: return scs.csr_matrix(np_toeplitz) elif all( isinstance(block, scs.csr_matrix) for block in np_toeplitz.flat): v_stacked = [ scs.bmat(np.atleast_2d(col).T).tocsc() for col in np_toeplitz.T ] return scs.bmat(np.atleast_2d(v_stacked)).tocsr() else: h_stacked = [ scs.bmat(np.atleast_2d(row)).tocsr() for row in np_toeplitz ] return scs.bmat(np.atleast_2d(h_stacked).T).tocsc() else: return np_toeplitz
def convertQImageToArray(image): """Convert a QImage to a numpy array. If QImage format is not Format_RGB888, Format_RGBA8888 or Format_ARGB32, it is first converted to one of this format depending on the presence of an alpha channel. The created numpy array is using a copy of the QImage data. :param QImage image: The QImage to convert. :return: The image array of RGB or RGBA channels of shape (height, width, channels (3 or 4)) :rtype: numpy.ndarray of uint8 """ rgba8888 = getattr(qt.QImage, 'Format_RGBA8888', None) # Only in Qt5 # Convert to supported format if needed if image.format() not in (qt.QImage.Format_ARGB32, qt.QImage.Format_RGB888, rgba8888): if image.hasAlphaChannel(): image = image.convertToFormat( rgba8888 if rgba8888 is not None else qt.QImage.Format_ARGB32) else: image = image.convertToFormat(qt.QImage.Format_RGB888) format_ = image.format() channels = 3 if format_ == qt.QImage.Format_RGB888 else 4 ptr = image.bits() if qt.BINDING not in ('PySide', 'PySide2'): ptr.setsize(image.byteCount()) if qt.BINDING == 'PyQt4' and sys.version_info[0] == 2: ptr = ptr.asstring() elif sys.version_info[0] == 3: # PySide with Python3 ptr = ptr.tobytes() # Create an array view on QImage internal data view = _as_strided( numpy.frombuffer(ptr, dtype=numpy.uint8), shape=(image.height(), image.width(), channels), strides=(image.bytesPerLine(), channels, 1)) if format_ == qt.QImage.Format_ARGB32: # Convert from ARGB to RGBA # Not a byte-ordered format: do care about endianness if sys.byteorder == 'little': # BGRA -> RGBA view = view[:, :, (2, 1, 0, 3)] else: # big endian: ARGB -> RGBA view = view[:, :, (1, 2, 3, 0)] # Format_RGB888 and Format_RGBA8888 do not need reshuffling channels: # They are byte-ordered and already in the right order return numpy.array(view, copy=True, order='C')
def reshape(array, newshape, order='A'): """ Similar as numpy.reshape but allow to had virtual dimension of size > 1 Virtual dimension are indicated by negative value in argument 'newshape' Parameters ---------- a : array_like Array to be reshaped. newshape : int or tuple of ints The new shape should be compatible with the original shape. One shape dimension can be None. In this case, the value is inferred from the length of the array and remaining dimensions. Any negative integer means a new dimension with this size. order : {'C', 'F', 'A'}, optional Determines whether the array data should be viewed as in C (row-major) order, FORTRAN (column-major) order, or the C/FORTRAN order should be preserved. Returns ------- reshaped_array : a view on input array if possible, otherwise a copy. See Also -------- numpy.reshape Example: -------- A = np.arange(12).reshape((3,4)) print A [[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]] B = reshape(A,(2,-3,None)) print B.shape (2, 3, 6) # second dimension of B is virtual: B[1,1,1] = 42 print B [[[ 0 1 2 3 4 5] [ 0 1 2 3 4 5] [ 0 1 2 3 4 5]] [[ 6 42 8 9 10 11] [ 6 42 8 9 10 11] [ 6 42 8 9 10 11]]] *** Warning: the order option has not been tested *** """ array = _np.reshape(array,[-1 if s is None else 1 if s<0 else s for s in newshape], order=order) shape = [abs(s) if s is not None else s2 for s,s2 in zip(newshape,array.shape)] strid = [st if s>=0 or s is None else 0 for st,s in zip(array.strides,newshape)] return _as_strided(array,shape=shape, strides=strid)
def convertQImageToArray(image): """Convert a QImage to a numpy array. If QImage format is not Format_RGB888, Format_RGBA8888 or Format_ARGB32, it is first converted to one of this format depending on the presence of an alpha channel. The created numpy array is using a copy of the QImage data. :param QImage image: The QImage to convert. :return: The image array of RGB or RGBA channels of shape (height, width, channels (3 or 4)) :rtype: numpy.ndarray of uint8 """ rgba8888 = getattr(qt.QImage, 'Format_RGBA8888', None) # Only in Qt5 # Convert to supported format if needed if image.format() not in (qt.QImage.Format_ARGB32, qt.QImage.Format_RGB888, rgba8888): if image.hasAlphaChannel(): image = image.convertToFormat( rgba8888 if rgba8888 is not None else qt.QImage.Format_ARGB32) else: image = image.convertToFormat(qt.QImage.Format_RGB888) format_ = image.format() channels = 3 if format_ == qt.QImage.Format_RGB888 else 4 ptr = image.bits() if qt.BINDING == 'PyQt5': ptr.setsize(image.byteCount()) elif qt.BINDING == 'PySide2': ptr = ptr.tobytes() else: raise RuntimeError("Unsupported Qt binding: %s" % qt.BINDING) # Create an array view on QImage internal data view = _as_strided( numpy.frombuffer(ptr, dtype=numpy.uint8), shape=(image.height(), image.width(), channels), strides=(image.bytesPerLine(), channels, 1)) if format_ == qt.QImage.Format_ARGB32: # Convert from ARGB to RGBA # Not a byte-ordered format: do care about endianness if sys.byteorder == 'little': # BGRA -> RGBA view = view[:, :, (2, 1, 0, 3)] else: # big endian: ARGB -> RGBA view = view[:, :, (1, 2, 3, 0)] # Format_RGB888 and Format_RGBA8888 do not need reshuffling channels: # They are byte-ordered and already in the right order return numpy.array(view, copy=True, order='C')
def stft(x, L, hop, transform=np.fft.fft, win=None, zp_back=0, zp_front=0): ''' Parameters ---------- x: input signal L: frame size hop: shift size between frames transform: the transform routine to apply (default FFT) win: the window to apply (default None) zp_back: zero padding to apply at the end of the frame zp_front: zero padding to apply at the beginning of the frame Returns ------- The STFT of x ''' # the transform size N = L + zp_back + zp_front # window needs to be same size as transform if (win is not None and len(win) != N): print('Window length need to be equal to frame length + zero padding.') sys.exit(-1) # reshape new_strides = (hop * x.strides[0], x.strides[0]) new_shape = ((len(x) - L) // hop + 1, L) y = _as_strided(x, shape=new_shape, strides=new_strides) # add the zero-padding y = np.concatenate( (np.zeros( (y.shape[0], zp_front)), y, np.zeros( (y.shape[0], zp_back))), axis=1) # apply window if needed if (win is not None): y = win * y # y = np.expand_dims(win, 0)*y # transform along rows Z = transform(y, axis=1) # apply transform return Z
def block_diag_dense_same_shape(mats, format=None, dtype=None): arrs = _atleast_3d_col(mats, dtype=dtype) k, n, m = arrs.shape arrs = arrs.reshape(k * n, m) vals = np.zeros(shape=(k * n, k * m), dtype=arrs.dtype) vals[:, :m] = arrs item_size = arrs.itemsize shape = (k, n, k * m) strides = ((k * n - 1) * m * item_size, k * m * item_size, item_size) strided = np.ascontiguousarray( _as_strided(vals, shape=shape, strides=strides)) block_diag = strided.reshape(n * k, m * k) return block_diag
def stft(x, L, hop, transform=np.fft.fft, win=None, zp_back=0, zp_front=0): '''短时傅里叶变换''' N = L + zp_back + zp_front if (win is not None and len(win) != N): print('Window length error.') sys.exit(-1) new_strides = (hop * x.strides[0], x.strides[0]) new_shape = ((len(x) - L) // hop + 1, L) y = _as_strided(x, shape=new_shape, strides=new_strides) y = np.concatenate((np.zeros((y.shape[0], zp_front), dtype=x.dtype), y, np.zeros((y.shape[0], zp_back), dtype=x.dtype)), axis=1) if (win is not None): y = win.astype(x.dtype) * y Z = transform(y, axis=1) return Z
def add_dim(array, axis=-1, size=1, shift=0): """ Insert a virtual dimension using stride tricks (i.e. broadcasting) *** The appended dimension is a repeated view over the same data *** call: new_array = add_dim(array, axis=-1, size=1, shift=0) :Input: - array a numpy ndarray - axis the index of the virtual axis to insert the axis number can be negative. If axis=-n: the added axis is the (array.ndim-n)th dimension of output array (if n=-1, add an axis at the end of input array) - size the number of element this new axis will have - shift (optional) if given, the added dimension becomes a shifted view in the input array. The ith element along the shift dimension start at element i*shift, which should be the index of an element in the given array. ** warning ** with shift, some valid indices point out of given array memory. Using it might CRASH PYTHON. Use at your own risk ** ******* ** :Output: if input array shape is S, the returned array has shape (S[:axis], size, S[axis:]) :Example: if A is a has 2x3x4 array, then B = add_dim(A,axis,5) will have shape: - (5,2,3,4) if axis= 0 - (2,3,5,4) if axis= 2 - (2,3,4,5) if axis= 3 or -1 B = add_dim(A,axis=-1,size=1) is the same as B = A[:,:,:,newaxis] B = add_dim(A,axis= 0,size=1) is the same as B = A[newaxis] :Note: The returned array is a (broadcasted) view on the input array. Changing its elements value will affect the original data. With default arguments (axis, size and shift), add_dim add a singleton axis at the end of input array """ A = _np.asanyarray(array) sh = _np.array(A.shape) st = _np.array(A.strides) # assert type of shift array and pad it with zeros if shift: shift = as_vector(shift,size=A.ndim,fvalue=0,fside=0) shift = _np.dot(shift, st) axis = _np.mod(axis,A.ndim+1) sh = _np.hstack((sh[:axis], size, sh[axis:])) st = _np.hstack((st[:axis], shift, st[axis:])) return _as_strided(A,shape=sh, strides=st)
if a.__class__ is b.__class__: a_l, a_h = bound(a) b_l, b_h = bound(b) if b_l >= a_h or a_l >= b_h: return False return True else: return False # {{{ as_strided implementation try: from numpy.lib.stride_tricks import as_strided as _as_strided _test_dtype = np.dtype([("a", np.float64), ("b", np.float64)], align=True) _test_result = _as_strided(np.zeros(10, dtype=_test_dtype)) if _test_result.dtype != _test_dtype: raise RuntimeError("numpy's as_strided is broken") as_strided = _as_strided except: # stolen from numpy to be compatible with older versions of numpy class _DummyArray(object): """ Dummy object that just exists to hang __array_interface__ dictionaries and possibly keep alive a reference to a base array. """ def __init__(self, interface, base=None): self.__array_interface__ = interface self.base = base def as_strided(x, shape=None, strides=None):
a_l, a_h = bound(a) b_l, b_h = bound(b) if b_l >= a_h or a_l >= b_h: return False return True else: return False # {{{ as_strided implementation try: from numpy.lib.stride_tricks import as_strided as _as_strided _test_dtype = np.dtype( [("a", np.float64), ("b", np.float64)], align=True) _test_result = _as_strided(np.zeros(10, dtype=_test_dtype)) if _test_result.dtype != _test_dtype: raise RuntimeError("numpy's as_strided is broken") as_strided = _as_strided except: # stolen from numpy to be compatible with older versions of numpy class _DummyArray(object): """ Dummy object that just exists to hang __array_interface__ dictionaries and possibly keep alive a reference to a base array. """ def __init__(self, interface, base=None): self.__array_interface__ = interface self.base = base def as_strided(x, shape=None, strides=None):
def reshape(array, newshape, order='A'): """ Similar as numpy.reshape but allow to had virtual dimension of size > 1 Virtual dimension are indicated by negative value in argument 'newshape' Parameters ---------- a : array_like Array to be reshaped. newshape : int or tuple of ints The new shape should be compatible with the original shape. One shape dimension can be None. In this case, the value is inferred from the length of the array and remaining dimensions. Any negative integer means a new dimension with this size. order : {'C', 'F', 'A'}, optional Determines whether the array data should be viewed as in C (row-major) order, FORTRAN (column-major) order, or the C/FORTRAN order should be preserved. Returns ------- reshaped_array : a view on input array if possible, otherwise a copy. See Also -------- numpy.reshape Example: -------- A = np.arange(12).reshape((3,4)) print A [[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]] B = reshape(A,(2,-3,None)) print B.shape (2, 3, 6) # second dimension of B is virtual: B[1,1,1] = 42 print B [[[ 0 1 2 3 4 5] [ 0 1 2 3 4 5] [ 0 1 2 3 4 5]] [[ 6 42 8 9 10 11] [ 6 42 8 9 10 11] [ 6 42 8 9 10 11]]] *** Warning: the order option has not been tested *** """ array = _np.reshape( array, [-1 if s is None else 1 if s < 0 else s for s in newshape], order=order) shape = [ abs(s) if s is not None else s2 for s, s2 in zip(newshape, array.shape) ] strid = [ st if s >= 0 or s is None else 0 for st, s in zip(array.strides, newshape) ] return _as_strided(array, shape=shape, strides=strid)
def add_dim(array, axis=-1, size=1, shift=0): """ Insert a virtual dimension using stride tricks (i.e. broadcasting) *** The appended dimension is a repeated view over the same data *** call: new_array = add_dim(array, axis=-1, size=1, shift=0) :Input: - array a numpy ndarray - axis the index of the virtual axis to insert the axis number can be negative. If axis=-n: the added axis is the (array.ndim-n)th dimension of output array (if n=-1, add an axis at the end of input array) - size the number of element this new axis will have - shift (optional) if given, the added dimension becomes a shifted view in the input array. The ith element along the shift dimension start at element i*shift, which should be the index of an element in the given array. ** warning ** with shift, some valid indices point out of given array memory. Using it might CRASH PYTHON. Use at your own risk ** ******* ** :Output: if input array shape is S, the returned array has shape (S[:axis], size, S[axis:]) :Example: if A is a has 2x3x4 array, then B = add_dim(A,axis,5) will have shape: - (5,2,3,4) if axis= 0 - (2,3,5,4) if axis= 2 - (2,3,4,5) if axis= 3 or -1 B = add_dim(A,axis=-1,size=1) is the same as B = A[:,:,:,newaxis] B = add_dim(A,axis= 0,size=1) is the same as B = A[newaxis] :Note: The returned array is a (broadcasted) view on the input array. Changing its elements value will affect the original data. With default arguments (axis, size and shift), add_dim add a singleton axis at the end of input array """ A = _np.asanyarray(array) sh = _np.array(A.shape) st = _np.array(A.strides) # assert type of shift array and pad it with zeros if shift: shift = as_vector(shift, size=A.ndim, fvalue=0, fside=0) shift = _np.dot(shift, st) axis = _np.mod(axis, A.ndim + 1) sh = _np.hstack((sh[:axis], size, sh[axis:])) st = _np.hstack((st[:axis], shift, st[axis:])) return _as_strided(A, shape=sh, strides=st)