Source code for pylops.signalprocessing.dct
__all__ = ["DCT"]
from typing import List, Optional, Union
import numpy as np
from scipy import fft
from pylops import LinearOperator
from pylops.utils._internal import _value_or_sized_to_tuple
from pylops.utils.decorators import reshaped
from pylops.utils.typing import DTypeLike, InputDimsLike, NDArray
[docs]class DCT(LinearOperator):
r"""Discrete Cosine Transform.
Apply 1D or ND-Cosine Transform along one or more ``axes`` of a multi-dimensional
array of size ``dims``.
This operator is an overload of :py:func:`scipy.fft.dctn` in forward mode and :py:func:`scipy.fft.idctn`
in adjoint mode.
Parameters
----------
dims : :obj:`int` or :obj:`tuple`
Number of samples for each dimension
type : :obj:`int`, optional
Type of DCT (see scipy's documentation for more details). Default type is 2.
axes : :obj:`int` or :obj:`list`, optional
Axes over which the DCT is computed. If ``None``, the transform is applied
over all axes.
workers : :obj:`int`, optional
Maximum number of workers to use for parallel computation. If negative,
the value wraps around from os.cpu_count().
dtype : :obj:`DTypeLike`, optional
Type of elements in input array.
name : :obj:`str`, optional
Name of operator (to be used by :func:`pylops.utils.describe.describe`)
Attributes
----------
shape : :obj:`tuple`
Operator shape
explicit : :obj:`bool`
Operator contains a matrix that can be solved explicitly
(``True``) or not (``False``)
Raises
------
ValueError
If ``type`` is different from 1, 2, 3, or 4.
Notes
-----
The DCT operator applies the Discrete Cosine Transform in forward mode and the Inverse Discrete Cosine Transform
in adjoint mode. This transform expresses a signal as a sum of cosine functions oscillating at different
frequencies. By doing so, no information is lost and the energy is compacted into the top left corner of the
transform. When applied to multi-dimensional arrays, the DCT operator is simply a cascade of one-dimensional DCT
operators acting along the different axes,
Finally, note that the DCT operator is implemented with normalization mode ``norm="ortho"`` to ensure symmetric
scaling.
"""
def __init__(
self,
dims: Union[int, InputDimsLike],
type: int = 2,
axes: Union[int, List[int]] = None,
dtype: DTypeLike = "float64",
workers: Optional[int] = None,
name: str = "C",
) -> None:
if type > 4 or type < 1:
raise ValueError("wrong type value, it can only be 1, 2, 3 or 4")
self.type = type
self.axes = axes
self.workers = workers
self.dims = _value_or_sized_to_tuple(dims)
super().__init__(
dtype=np.dtype(dtype), dims=self.dims, dimsd=self.dims, name=name
)
@reshaped
def _matvec(self, x: NDArray) -> NDArray:
return fft.dctn(
x, axes=self.axes, type=self.type, norm="ortho", workers=self.workers
)
@reshaped
def _rmatvec(self, x: NDArray) -> NDArray:
return fft.idctn(
x, axes=self.axes, type=self.type, norm="ortho", workers=self.workers
)