mrpro.operators.WaveletOp

class mrpro.operators.WaveletOp[source]

Bases: LinearOperator

Wavelet operator class.

__init__(domain_shape: Sequence[int] | None = None, dim: tuple[int] | tuple[int, int] | tuple[int, int, int] = (-2, -1), wavelet_name: Literal['haar', 'db1', 'db2', 'db3', 'db4', 'db5', 'db6', 'db7', 'db8', 'db9', 'db10', 'db11', 'db12', 'db13', 'db14', 'db15', 'db16', 'db17', 'db18', 'db19', 'db20', 'db21', 'db22', 'db23', 'db24', 'db25', 'db26', 'db27', 'db28', 'db29', 'db30', 'db31', 'db32', 'db33', 'db34', 'db35', 'db36', 'db37', 'db38', 'sym2', 'sym3', 'sym4', 'sym5', 'sym6', 'sym7', 'sym8', 'sym9', 'sym10', 'sym11', 'sym12', 'sym13', 'sym14', 'sym15', 'sym16', 'sym17', 'sym18', 'sym19', 'sym20', 'coif1', 'coif2', 'coif3', 'coif4', 'coif5', 'coif6', 'coif7', 'coif8', 'coif9', 'coif10', 'coif11', 'coif12', 'coif13', 'coif14', 'coif15', 'coif16', 'coif17', 'bior1.1', 'bior1.3', 'bior1.5', 'bior2.2', 'bior2.4', 'bior2.6', 'bior2.8', 'bior3.1', 'bior3.3', 'bior3.5', 'bior3.7', 'bior3.9', 'bior4.4', 'bior5.5', 'bior6.8', 'rbio1.1', 'rbio1.3', 'rbio1.5', 'rbio2.2', 'rbio2.4', 'rbio2.6', 'rbio2.8', 'rbio3.1', 'rbio3.3', 'rbio3.5', 'rbio3.7', 'rbio3.9', 'rbio4.4', 'rbio5.5', 'rbio6.8', 'dmey', 'gaus1', 'gaus2', 'gaus3', 'gaus4', 'gaus5', 'gaus6', 'gaus7', 'gaus8', 'mexh', 'morl', 'cgau1', 'cgau2', 'cgau3', 'cgau4', 'cgau5', 'cgau6', 'cgau7', 'cgau8', 'shan', 'fbsp', 'cmor'] = 'db4', level: int | None = None)[source]

Wavelet operator.

For complex images the wavelet coefficients are calculated for real and imaginary part separately.

For a 2D image, the coefficients are labeled [aa, (ad_n, da_n, dd_n), ..., (ad_1, da_1, dd_1)] where a refers to the approximation coefficients and d to the detail coefficients. The index indicates the level.

Parameters:
  • domain_shape (Sequence[int] | None, default: None) – Shape of domain where wavelets are calculated. If set to None the shape is taken from the input of the forward operator. The adjoint operator will raise an error.

  • dim (tuple[int] | tuple[int, int] | tuple[int, int, int], default: (-2, -1)) – Dimensions (axes) where wavelets are calculated

  • wavelet_name (Literal['haar', 'db1', 'db2', 'db3', 'db4', 'db5', 'db6', 'db7', 'db8', 'db9', 'db10', 'db11', 'db12', 'db13', 'db14', 'db15', 'db16', 'db17', 'db18', 'db19', 'db20', 'db21', 'db22', 'db23', 'db24', 'db25', 'db26', 'db27', 'db28', 'db29', 'db30', 'db31', 'db32', 'db33', 'db34', 'db35', 'db36', 'db37', 'db38', 'sym2', 'sym3', 'sym4', 'sym5', 'sym6', 'sym7', 'sym8', 'sym9', 'sym10', 'sym11', 'sym12', 'sym13', 'sym14', 'sym15', 'sym16', 'sym17', 'sym18', 'sym19', 'sym20', 'coif1', 'coif2', 'coif3', 'coif4', 'coif5', 'coif6', 'coif7', 'coif8', 'coif9', 'coif10', 'coif11', 'coif12', 'coif13', 'coif14', 'coif15', 'coif16', 'coif17', 'bior1.1', 'bior1.3', 'bior1.5', 'bior2.2', 'bior2.4', 'bior2.6', 'bior2.8', 'bior3.1', 'bior3.3', 'bior3.5', 'bior3.7', 'bior3.9', 'bior4.4', 'bior5.5', 'bior6.8', 'rbio1.1', 'rbio1.3', 'rbio1.5', 'rbio2.2', 'rbio2.4', 'rbio2.6', 'rbio2.8', 'rbio3.1', 'rbio3.3', 'rbio3.5', 'rbio3.7', 'rbio3.9', 'rbio4.4', 'rbio5.5', 'rbio6.8', 'dmey', 'gaus1', 'gaus2', 'gaus3', 'gaus4', 'gaus5', 'gaus6', 'gaus7', 'gaus8', 'mexh', 'morl', 'cgau1', 'cgau2', 'cgau3', 'cgau4', 'cgau5', 'cgau6', 'cgau7', 'cgau8', 'shan', 'fbsp', 'cmor'], default: 'db4') – Name of wavelets

  • level (int | None, default: None) – Highest wavelet level. If set to None, the highest possible level is calculated based on the domain shape.

Raises:
  • ValueError – If wavelets are calculated for more than three dimensions.

  • ValueError – If wavelet dimensions and domain shape do not match.

  • NotImplementedError – If any dimension of the domain shape is odd. Adjoint will lead to the wrong domain shape.

property H: LinearOperator[source]

Adjoint operator.

Obtains the adjoint of an instance of this operator as an AdjointLinearOperator, which itself is a an LinearOperator that can be applied to tensors.

Note: linear_operator.H.H == linear_operator

property gram: LinearOperator[source]

Gram operator.

For a LinearOperator \(A\), the self-adjoint Gram operator is defined as \(A^H A\).

Note

This is the inherited default implementation.

__call__(x: Tensor) tuple[Tensor][source]

Apply wavelet decomposition to the input tensor.

This method calculates the wavelet coefficients of the input (image) data along the specified dimensions. For complex inputs, the wavelet transform is applied to the real and imaginary parts separately. The resulting coefficients from different levels and orientations are stacked along a single dimension.

Parameters:

x (Tensor) – Input (image) data tensor.

Returns:

The wavelet coefficients, stacked along one dimension. The first wavelet dimension specified in dim during initialization is used for stacking.

Raises:

ValueError – If the dimensions along which wavelets are to be calculated (specified during initialization) are not unique after normalization.

adjoint(coefficients_stack: Tensor) tuple[Tensor][source]

Apply inverse wavelet transform (reconstruction) to wavelet coefficients.

This method reconstructs the (image) data from its wavelet coefficients. The input coefficients_stack is first unstacked into a list of coefficients for different levels and orientations, and then the inverse wavelet transform is applied. For complex inputs, the transform is applied to real and imaginary parts separately.

Parameters:

coefficients_stack (Tensor) – Tensor of wavelet coefficients, stacked along one dimension (assumed to be the first wavelet dimension specified in dim during initialization).

Returns:

The reconstructed (image) data tensor.

Raises:
  • ValueError – If domain_shape was not defined during operator initialization.

  • ValueError – If the dimensions along which wavelets were calculated (specified during initialization) are not unique after normalization.

forward(x: Tensor) tuple[Tensor][source]

Apply forward of WaveletOp.

Note

Prefer calling the instance of the WaveletOp operator as operator(x) over directly calling this method. See this PyTorch discussion.

operator_norm(initial_value: Tensor, dim: Sequence[int] | None, max_iterations: int = 20, relative_tolerance: float = 1e-4, absolute_tolerance: float = 1e-5, callback: Callable[[Tensor], None] | None = None) Tensor[source]

Power iteration for computing the operator norm of the operator.

Parameters:
  • initial_value (Tensor) – initial value to start the iteration; must be element of the domain. if the initial value contains a zero-vector for one of the considered problems, the function throws an ValueError.

  • dim (Sequence[int] | None) –

    The dimensions of the tensors on which the operator operates. The choice of dim determines how the operator norm is inperpreted. For example, for a matrix-vector multiplication with a batched matrix tensor of shape (batch1, batch2, row, column) and a batched input tensor of shape (batch1, batch2, row):

    • If dim=None, the operator is considered as a block diagonal matrix with batch1*batch2 blocks and the result is a tensor containing a single norm value (shape (1, 1, 1)).

    • If dim=(-1), batch1*batch2 matrices are considered, and for each a separate operator norm is computed.

    • If dim=(-2,-1), batch1 matrices with batch2 blocks are considered, and for each matrix a separate operator norm is computed.

    Thus, the choice of dim determines implicitly determines the domain of the operator.

  • max_iterations (int, default: 20) – maximum number of iterations

  • relative_tolerance (float, default: 1e-4) – absolute tolerance for the change of the operator-norm at each iteration; if set to zero, the maximal number of iterations is the only stopping criterion used to stop the power iteration.

  • absolute_tolerance (float, default: 1e-5) – absolute tolerance for the change of the operator-norm at each iteration; if set to zero, the maximal number of iterations is the only stopping criterion used to stop the power iteration.

  • callback (Callable[[Tensor], None] | None, default: None) – user-provided function to be called at each iteration

Returns:

An estimaton of the operator norm. Shape corresponds to the shape of the input tensor initial_value with the dimensions specified in dim reduced to a single value. The pointwise multiplication of initial_value with the result of the operator norm will always be well-defined.

__add__(other: LinearOperator | Tensor | complex) LinearOperator[source]
__add__(other: Operator[Tensor, tuple[Tensor]]) Operator[Tensor, tuple[Tensor]]

Operator addition.

Returns lambda x: self(x) + other(x) if other is a operator, lambda x: self(x) + other if other is a tensor

__and__(other: LinearOperator) LinearOperatorMatrix[source]

Vertical stacking of two LinearOperators.

A&B is a LinearOperatorMatrix with two rows, with (A&B)(x) == (A(x), B(x)). See mrpro.operators.LinearOperatorMatrix for more information.

__matmul__(other: LinearOperator) LinearOperator[source]
__matmul__(other: Operator[Unpack[Tin2], tuple[Tensor]] | Operator[Unpack[Tin2], tuple[Tensor, ...]]) Operator[Unpack[Tin2], tuple[Tensor]]

Operator composition.

Returns lambda x: self(other(x))

__mul__(other: Tensor | complex) LinearOperator[source]

Operator elementwise left multiplication with tensor/scalar.

Returns lambda x: self(x*other)

__or__(other: LinearOperator) LinearOperatorMatrix[source]

Horizontal stacking of two LinearOperators.

A|B is a LinearOperatorMatrix with two columns, with (A|B)(x1,x2) == A(x1) + B(x2). See mrpro.operators.LinearOperatorMatrix for more information.

__radd__(other: Tensor | complex) LinearOperator[source]

Operator addition.

Returns lambda x: self(x) + other*x

__rmul__(other: Tensor | complex) LinearOperator[source]

Operator elementwise right multiplication with tensor/scalar.

Returns lambda x: other*self(x)