A naive :math:`O(N^2)` implementation of the 1D discrete cosine transform-II (DCT-II). Notes ----- For a signal :math:`\mathbf{x} = [x_1, \ldots, x_N]` consisting of `N` samples, the `k` th DCT coefficient, :math:`c_k`, is .. math:: c_k = 2 \sum_{n=0}^{N-1} x_
(frame, orthonormal=True)
| 159 | |
| 160 | |
| 161 | def DCT(frame, orthonormal=True): |
| 162 | """ |
| 163 | A naive :math:`O(N^2)` implementation of the 1D discrete cosine transform-II |
| 164 | (DCT-II). |
| 165 | |
| 166 | Notes |
| 167 | ----- |
| 168 | For a signal :math:`\mathbf{x} = [x_1, \ldots, x_N]` consisting of `N` |
| 169 | samples, the `k` th DCT coefficient, :math:`c_k`, is |
| 170 | |
| 171 | .. math:: |
| 172 | |
| 173 | c_k = 2 \sum_{n=0}^{N-1} x_n \cos(\pi k (2 n + 1) / (2 N)) |
| 174 | |
| 175 | where `k` ranges from :math:`0, \ldots, N-1`. |
| 176 | |
| 177 | The DCT is highly similar to the DFT -- whereas in a DFT the basis |
| 178 | functions are sinusoids, in a DCT they are restricted solely to cosines. A |
| 179 | signal's DCT representation tends to have more of its energy concentrated |
| 180 | in a smaller number of coefficients when compared to the DFT, and is thus |
| 181 | commonly used for signal compression. [1] |
| 182 | |
| 183 | .. [1] Smoother signals can be accurately approximated using fewer DFT / DCT |
| 184 | coefficients, resulting in a higher compression ratio. The DCT naturally |
| 185 | yields a continuous extension at the signal boundaries due its use of |
| 186 | even basis functions (cosine). This in turn produces a smoother |
| 187 | extension in comparison to DFT or DCT approximations, resulting in a |
| 188 | higher compression. |
| 189 | |
| 190 | Parameters |
| 191 | ---------- |
| 192 | frame : :py:class:`ndarray <numpy.ndarray>` of shape `(N,)` |
| 193 | A signal frame consisting of N samples |
| 194 | orthonormal : bool |
| 195 | Scale to ensure the coefficient vector is orthonormal. Default is True. |
| 196 | |
| 197 | Returns |
| 198 | ------- |
| 199 | dct : :py:class:`ndarray <numpy.ndarray>` of shape `(N,)` |
| 200 | The discrete cosine transform of the samples in `frame`. |
| 201 | """ |
| 202 | N = len(frame) |
| 203 | out = np.zeros_like(frame) |
| 204 | for k in range(N): |
| 205 | for (n, xn) in enumerate(frame): |
| 206 | out[k] += xn * np.cos(np.pi * k * (2 * n + 1) / (2 * N)) |
| 207 | scale = np.sqrt(1 / (4 * N)) if k == 0 else np.sqrt(1 / (2 * N)) |
| 208 | out[k] *= 2 * scale if orthonormal else 2 |
| 209 | return out |
| 210 | |
| 211 | |
| 212 | def __DCT2(frame): |