mr2.operators.FiniteDifferenceOp

class mr2.operators.FiniteDifferenceOp[source]

Bases: LinearOperator

Finite-difference operator.

Computes directional discrete derivatives along the axes in dim (for example dim=(-2, -1) for spatial (y, x) gradients). One directional derivative is computed per axis and stacked along a new leading dimension.

Each output channel i computes finite differences along axis dim[i]. For mode='forward', values follow

\[y_i[k] = x[k + e_i] - x[k],\]

where \(e_i\) is a one-step shift along axis dim[i]. 'central' and 'backward' use the stencils \(\\tfrac{1}{2}(-1,0,1)\) and \((-1,1,0)\).

For input x with shape S, op(x) returns a tensor with shape (len(dim), *S) where channel i corresponds to axis dim[i]. Supported schemes are 'forward', 'backward', and 'central'. Boundary handling is controlled by pad_mode ('zeros' or 'circular').

__init__(dim: Sequence[int], mode: Literal['central', 'forward', 'backward'] = 'forward', pad_mode: Literal['zeros', 'circular'] = 'zeros') None[source]

Initialize a finite-difference operator.

Parameters:
  • dim (Sequence[int]) – Axes along which finite differences are computed. The order defines the order of directional channels in the output.

  • mode (Literal['central', 'forward', 'backward'], default: 'forward') – Finite-difference scheme used to construct the 1D kernel.

  • pad_mode (Literal['zeros', 'circular'], default: 'zeros') – Boundary handling used during filtering. 'zeros' maps to constant-zero padding, 'circular' to periodic padding.

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 directional finite differences.

Computes one directional derivative per axis in dim and stacks the results along a new leading dimension.

Parameters:

x (Tensor) – Input tensor from the operator domain.

Returns:

Single tensor of shape (len(dim), *x.shape) containing directional finite differences in the same order as dim.

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

Apply the adjoint of the finite-difference operator.

Expects stacked directional components (as returned by forward), applies the per-direction adjoint filter (kernel flipped in 1D), and sums across directions.

Parameters:

y (Tensor) – Directional components stacked along the leading axis. y.shape[0] must equal len(dim).

Returns:

Tensor in the original domain shape.

Raises:

ValueError – If the leading dimension of y does not match len(dim).

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

Apply forward of FiniteDifferenceOp.

Note

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

static finite_difference_kernel(mode: Literal['central', 'forward', 'backward']) Tensor[source]

Return the 1D finite-difference kernel for a given mode.

Parameters:

mode (Literal['central', 'forward', 'backward']) – Difference scheme: 'forward', 'backward', or 'central'.

Returns:

1D kernel tensor of length 3.

Raises:

ValueError – If mode is not one of 'central', 'forward', or 'backward'.

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

__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 mr2.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)