def lowpass_filter(data, max_freq=None): """ Implements a low-pass filter on the input array, by DCTing the input, mapping all but the lowest `max_freq` modes to zero, and then inverting the transform. Parameters ---------- data : numpy.array, The vector to low-pass filter max_freq : None or int, optional The highest frequency to keep. If None then it keeps the minimum of 50 or l/10 frequencies, where l is the length of the data vector Returns ------- numpy.array The low-pass-filtered data. """ n = len(data) if max_freq is None: max_freq = min(int(_np.ceil(n / 10)), 50) modes = _dct(data, norm='ortho') if max_freq < n - 1: modes[max_freq + 1:] = _np.zeros(len(data) - max_freq - 1) out = _idct(modes, norm='ortho') return out
def DCT(x, counts=1, null_hypothesis=None): """ Returns the Type-II discrete cosine transform of y, with an orthogonal normalization, where y is an array with elements related to the x array by y[k] = (x[k] - null_hypothesis[k])/normalizer; normalizer = sqrt(counts*null_hypothesis[k]*(1-null_hypothesis[k])). If null_hypothesis is None, then null_hypothesis[k] is mean(x)/counts, for all k. This is with the exception that when mean(x)/counts = 0 or 1 (when the above y[k] is ill-defined), in which case the zero vector is returned. Parameters ---------- x : array Data string, on which the normalization and discrete cosine transformation is performed. If counts is not specified, this must be a bit string. null_hypothesis : array, optional If not None, an array to use in the normalization before the DCT. If None, it is taken to be an array in which every element is the mean of x. counts : int, optional TODO Returns ------- array The DCT modes described above. """ x_mean = _np.mean(x) N = len(x) assert ( min(counts * _np.ones(N) - x) >= 0), "The number of counts must be >= to the maximum of the data array!" assert (min(x) >= 0), "The elements of the data array must be >= 0" # If the null hypothesis is not specified, we take our null hypothesis to be a constant bias # coin, with the bias given by the mean of the data / number of counts. if null_hypothesis is None: null_hypothesis = x_mean / counts if null_hypothesis <= 0 or null_hypothesis >= 1: return _np.zeros(N) else: assert (min(null_hypothesis) > 0 and max(null_hypothesis) < 1 ), "All element of null_hypothesis must be in (0,1)!" assert ( len(null_hypothesis) == N ), "The null hypothesis array must be the same length as the data array!" return _dct((x - counts * null_hypothesis) / _np.sqrt(counts * null_hypothesis * (1 - null_hypothesis)), norm='ortho')
def low_pass_filter(data, max_freq=None): """ TODO: docstring """ n = len(data) if max_freq is None: max_freq = min(int(np.ceil(n / 10)), 50) modes = _dct(data, norm='ortho') if max_freq < n - 1: modes[max_freq + 1:] = _np.zeros(len(data) - max_freq - 1) return _idct(modes, norm='ortho')
def amplitudes_at_frequencies(freq_indices, timeseries, times=None, transform='dct'): """ Finds the amplitudes in the data at the specified frequency indices. Todo: better docstring. Currently only works for the DCT. """ amplitudes = {} for o in timeseries.keys(): if transform == 'dct': temp = _dct(timeseries[o], norm='ortho')[freq_indices] / _np.sqrt(len(timeseries[o]) / 2) if 0. in freq_indices: temp[0] = temp[0] / _np.sqrt(2) amplitudes[o] = list(temp) else: raise NotImplementedError("This function only currently works for the DCT!") return amplitudes
def dct(x, null_hypothesis=None, counts=1): """ Returns the Type-II discrete cosine transform of y, with an orthogonal normalization, where y = (x - counts * null_hypothesis) / sqrt(counts * null_hypothesis * (1-null_hypothesis)), where the arithmetic is element-wise, and `null_hypothesis` is a vector in (0,1). If `null_hypothesis` is None it is set to the mean of x. If that mean is 0 or 1 then the vector of all ones, except for the first element which is set to zero, is returned. Parameters ---------- x : array Data string, on which the normalization and discrete cosine transformation is performed. If counts is not specified, this must be a bit string. null_hypothesis : array, optional If not None, an array to use in the normalization before the dct. If None, it is taken to be an array in which every element is the mean of x. counts : int, optional A factor in the normalization, that should correspond to the counts-per-timestep (so for full time resolution this is 1). Returns ------- array The DCT modes described above. """ standardized_x = standardizer(x, null_hypothesis, counts) if standardized_x is None: out = _np.ones(len(x)) out[0] = 0. return out modes = _dct(standardized_x, norm='ortho') return modes
def dct(x, type=2, n=None, axis=-1, norm='ortho'): # @ReservedAssignment """ Return the Discrete Cosine Transform of arbitrary type sequence x. Parameters ---------- x : array_like The input array. type : {1, 2, 3}, optional Type of the DCT (see Notes). Default type is 2. n : int, optional Length of the transform. axis : int, optional Axis over which to compute the transform. norm : {None, 'ortho'}, optional Normalization mode (see Notes). Default is 'ortho'. Returns ------- y : ndarray of real The transformed input array. See Also -------- idct Notes ----- For a single dimension array ``x``, ``dct(x, norm='ortho')`` is equal to MATLAB ``dct(x)``. There are theoretically 8 types of the DCT, only the first 3 types are implemented in scipy. 'The' DCT generally refers to DCT type 2, and 'the' Inverse DCT generally refers to DCT type 3. type I ~~~~~~ There are several definitions of the DCT-I; we use the following (for ``norm=None``):: N-2 y[k] = x[0] + (-1)**k x[N-1] + 2 * sum x[n]*cos(pi*k*n/(N-1)) n=1 Only None is supported as normalization mode for DCT-I. Note also that the DCT-I is only supported for input size > 1 type II ~~~~~~~ There are several definitions of the DCT-II; we use the following (for ``norm=None``):: N-1 y[k] = 2* sum x[n]*cos(pi*k*(2n+1)/(2*N)), 0 <= k < N. n=0 If ``norm='ortho'``, ``y[k]`` is multiplied by a scaling factor `f`:: f = sqrt(1/(4*N)) if k = 0, f = sqrt(1/(2*N)) otherwise. Which makes the corresponding matrix of coefficients orthonormal (``OO' = Id``). type III ~~~~~~~~ There are several definitions, we use the following (for ``norm=None``):: N-1 y[k] = x[0] + 2 * sum x[n]*cos(pi*(k+0.5)*n/N), 0 <= k < N. n=1 or, for ``norm='ortho'`` and 0 <= k < N:: N-1 y[k] = x[0] / sqrt(N) + sqrt(1/N) * sum x[n]*cos(pi*(k+0.5)*n/N) n=1 The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up to a factor `2N`. The orthonormalized DCT-III is exactly the inverse of the orthonormalized DCT-II. Examples -------- >>> import numpy as np >>> x = np.arange(5) >>> np.allclose(x, idct(dct(x))) True >>> np.allclose(x, dct(idct(x))) True References ---------- http://en.wikipedia.org/wiki/Discrete_cosine_transform http://users.ece.utexas.edu/~bevans/courses/ee381k/lectures/ 'A Fast Cosine Transform in One and Two Dimensions', by J. Makhoul, `IEEE Transactions on acoustics, speech and signal processing` vol. 28(1), pp. 27-34, http://dx.doi.org/10.1109/TASSP.1980.1163351 (1980). """ return _dct(x, type, n, axis, norm)
def dct(x, type=2, n=None, axis=-1, norm='ortho'): # @ReservedAssignment ''' Return the Discrete Cosine Transform of arbitrary type sequence x. Parameters ---------- x : array_like The input array. type : {1, 2, 3}, optional Type of the DCT (see Notes). Default type is 2. n : int, optional Length of the transform. axis : int, optional Axis over which to compute the transform. norm : {None, 'ortho'}, optional Normalization mode (see Notes). Default is 'ortho'. Returns ------- y : ndarray of real The transformed input array. See Also -------- idct Notes ----- For a single dimension array ``x``, ``dct(x, norm='ortho')`` is equal to MATLAB ``dct(x)``. There are theoretically 8 types of the DCT, only the first 3 types are implemented in scipy. 'The' DCT generally refers to DCT type 2, and 'the' Inverse DCT generally refers to DCT type 3. type I ~~~~~~ There are several definitions of the DCT-I; we use the following (for ``norm=None``):: N-2 y[k] = x[0] + (-1)**k x[N-1] + 2 * sum x[n]*cos(pi*k*n/(N-1)) n=1 Only None is supported as normalization mode for DCT-I. Note also that the DCT-I is only supported for input size > 1 type II ~~~~~~~ There are several definitions of the DCT-II; we use the following (for ``norm=None``):: N-1 y[k] = 2* sum x[n]*cos(pi*k*(2n+1)/(2*N)), 0 <= k < N. n=0 If ``norm='ortho'``, ``y[k]`` is multiplied by a scaling factor `f`:: f = sqrt(1/(4*N)) if k = 0, f = sqrt(1/(2*N)) otherwise. Which makes the corresponding matrix of coefficients orthonormal (``OO' = Id``). type III ~~~~~~~~ There are several definitions, we use the following (for ``norm=None``):: N-1 y[k] = x[0] + 2 * sum x[n]*cos(pi*(k+0.5)*n/N), 0 <= k < N. n=1 or, for ``norm='ortho'`` and 0 <= k < N:: N-1 y[k] = x[0] / sqrt(N) + sqrt(1/N) * sum x[n]*cos(pi*(k+0.5)*n/N) n=1 The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up to a factor `2N`. The orthonormalized DCT-III is exactly the inverse of the orthonormalized DCT-II. References ---------- http://en.wikipedia.org/wiki/Discrete_cosine_transform 'A Fast Cosine Transform in One and Two Dimensions', by J. Makhoul, `IEEE Transactions on acoustics, speech and signal processing` vol. 28(1), pp. 27-34, http://dx.doi.org/10.1109/TASSP.1980.1163351 (1980). ''' farr = np.asfarray if np.iscomplex(x).any(): return _dct(farr(x.real), type, n, axis, norm) + \ 1j * _dct(farr(x.imag), type, n, axis, norm) else: return _dct(farr(x), type, n, axis, norm)
def dctn(x, type=2, axis=None, norm='ortho'): # @ReservedAssignment ''' DCTN N-D discrete cosine transform. Y = DCTN(X) returns the discrete cosine transform of X. The array Y is the same size as X and contains the discrete cosine transform coefficients. This transform can be inverted using IDCTN. DCTN(X,axis) applies the DCTN operation across the dimension axis. Class Support ------------- Input array can be numeric or logical. The returned array is of class double. Reference --------- Narasimha M. et al, On the computation of the discrete cosine transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936. Example ------- RGB = imread('autumn.tif'); I = rgb2gray(RGB); J = dctn(I); imshow(log(abs(J)),[]), colormap(jet), colorbar The commands below set values less than magnitude 10 in the DCT matrix to zero, then reconstruct the image using the inverse DCT. J(abs(J)<10) = 0; K = idctn(J); figure, imshow(I) figure, imshow(K,[0 255]) See also -------- idctn, dct, idct ''' y = np.atleast_1d(x) shape0 = y.shape if axis is None: y = y.squeeze() # Working across singleton dimensions is useless ndim = y.ndim isvector = max(shape0) == y.size if isvector: if ndim == 1: y = np.atleast_2d(y) y = y.T elif y.shape[0] == 1: if axis == 0: return x elif axis == 1: axis = 0 y = y.T elif axis == 1: return y if np.iscomplex(y).any(): y = dctn(y.real, type, axis, norm) + 1j * \ dctn(y.imag, type, axis, norm) else: y = np.asfarray(y) for dim in range(ndim): y = y.transpose(np.roll(range(y.ndim), -1)) #y = shiftdim(y,1) if axis is not None and dim != axis: continue y = _dct(y, type, norm=norm) return y.reshape(shape0)
def dctn(x, type=2, axis=None, norm='ortho'): # @ReservedAssignment ''' DCTN N-D discrete cosine transform. Y = DCTN(X) returns the discrete cosine transform of X. The array Y is the same size as X and contains the discrete cosine transform coefficients. This transform can be inverted using IDCTN. DCTN(X,axis) applies the DCTN operation across the dimension axis. Class Support ------------- Input array can be numeric or logical. The returned array is of class double. Reference --------- Narasimha M. et al, On the computation of the discrete cosine transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936. Example ------- RGB = imread('autumn.tif'); I = rgb2gray(RGB); J = dctn(I); imshow(log(abs(J)),[]), colormap(jet), colorbar The commands below set values less than magnitude 10 in the DCT matrix to zero, then reconstruct the image using the inverse DCT. J(abs(J)<10) = 0; K = idctn(J); figure, imshow(I) figure, imshow(K,[0 255]) See also -------- idctn, dct, idct ''' y = np.atleast_1d(x) shape0 = y.shape if axis is None: y = y.squeeze() # Working across singleton dimensions is useless ndim = y.ndim isvector = max(shape0) == y.size if isvector: if ndim == 1: y = np.atleast_2d(y) y = y.T elif y.shape[0] == 1: if axis == 0: return x elif axis == 1: axis = 0 y = y.T elif axis == 1: return y if np.iscomplex(y).any(): y = dctn(y.real, type, axis, norm) + 1j * \ dctn(y.imag, type, axis, norm) else: y = np.asfarray(y) for dim in range(ndim): y = y.transpose(np.roll(list(range(y.ndim)), -1)) #y = shiftdim(y,1) if axis is not None and dim != axis: continue y = _dct(y, type, norm=norm) return y.reshape(shape0)