mr2.operators.DifferentiableDictionaryMatchOp

class mr2.operators.DifferentiableDictionaryMatchOp[source]

Bases: Operator[Tensor, tuple[Unpack[Tin]]]

Differentiable Dictionary Matching Operator.

This operator can be used for dictionary matching, for example in magnetic resonance fingerprinting.

It performs absolute normalized dot product matching between a dictionary of signals, i.e. find the entry \(d^*\) in the dictionary maximizing \(\left|\frac{d}{\|d\|} \cdot \frac{y}{\|y\|}\right|\) and uses the associated signal model parameters \(x\) generating the matching signal \(d^*=d(x)\) as support points for a linear approximation of the signal model.

At initialization, a signal model needs to be provided. Afterwards append with different x values should be called to add entries to the dictionary. This operator then calculates for each x value the signal returned by the model and precalculates the Jacobians of the signal model at these support points. To perform a match, use __call__ and supply some y values. The operator will then perform the dot product matching and return the associated x values.

Note

The Gauss-Newton refinement step is differentiable in input_signal. The dictionary lookup itself (argmax) is non-differentiable.

__init__(generating_function: Callable[[Unpack[Tin]], tuple[Tensor]], index_of_scaling_parameter: int | None = None, batch_size: int = 64 * 1024)[source]

Initialize DictionaryMatchOp.

Parameters:
  • generating_function (Callable[[Unpack[TypeVarTuple]], tuple[Tensor]]) – signal model that takes n inputs and returns a signal y.

  • index_of_scaling_parameter (int | None, default: None) –

    Normalized dot product matching is insensitive to overall signal scaling. A scaling factor (e.g. the equilibrium magnetization m0 in InversionRecovery) is calculated after the dictionary matching if index_of_scaling_parameter is not None. index_of_scaling_parameter should set to the index of the scaling parameter in the signal model.

    Example:

    For ~mr2.operators.models.InversionRecovery the parameters are [m0, t1] and therefore index_of_scaling_parameter should be set to 0. The operator will then return t1 estimated via dictionary matching and m0 via a post-processing step. If index_of_scaling_parameter is None, the value returned for m0 will be meaningless.

  • batch_size (int, default: 64 * 1024) – Size of the chunks to split the input signal into for batch processing. Reduce to save memory.

__call__(input_signal: Tensor, *, prior: tuple[Unpack[Tin]] | None = None, prior_precision: tuple[Unpack[Tin]] | Tensor | None = None, return_signal: Literal[False] = False) tuple[Unpack[Tin]][source]
__call__(input_signal: Tensor, *, prior: tuple[Unpack[Tin]] | None = None, prior_precision: tuple[Unpack[Tin]] | Tensor | None = None, return_signal: Literal[True] = Ellipsis) tuple[tuple[Unpack[Tin]], Tensor]

Perform dot-product matching.

Performs dictionary matching, optionally with a prior, followed by a single Gauss-Newton refinement step using precomputed Jacobians. The solution step is differentiable in input_signal.

Parameters:
  • input_signal (Tensor) – Input signal(s) to match against the dictionary. Expected shape is (m, ...), where m is the signal dimension (e.g., number of time points) and (...) are batch dimensions.

  • prior (tuple[Unpack[TypeVarTuple]] | None, default: None) – Prior means, one tensor per returned parameter. Each tensor must be broadcastable to the batch/image shape input_signal.shape[1:].

  • prior_precision (tuple[Unpack[TypeVarTuple]] | Tensor | None, default: None) – Diagonal prior precisions, one tensor per returned parameter, or a single tensor to use for all parameters. Each tensor must be broadcastable to input_signal.shape[1:] and contain finite, non-negative values. prior and prior_precision must be provided together.

  • return_signal (bool, default: False) – If True, return the signal approximation as well.

Returns:

A tuple of tensors representing the parameters x from the dictionary that best matched the input signal(s). Each tensor in the tuple corresponds to a parameter, and their shapes will match the batch dimensions of input_signal.

forward(input_signal: Tensor, *, prior: tuple[Unpack[Tin]] | None = None, prior_precision: tuple[Unpack[Tin]] | Tensor | None = None, return_signal: bool = False) tuple[tuple[Unpack[Tin]], Tensor] | tuple[Unpack[Tin]][source]

Apply forward of DictionaryMatchOp.

Note

Prefer calling the instance as operator(x) over directly calling this method.

append(*x: Unpack[Tin]) Self[source]

Append x values to the dictionary.

Parameters:

x (Unpack[TypeVarTuple]) – points where the signal model will be evaluated. For signal models with n inputs, n tensors should be provided. Broadcasting is supported.

Returns:

Self

__add__(other: Operator[Unpack[Tin], Tout]) Operator[Unpack[Tin], Tout][source]
__add__(other: Tensor | complex) Operator[Unpack[Tin], tuple[Unpack[Tin]]]

Operator addition.

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

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

Operator composition.

Returns lambda x: self(other(x))

__mul__(other: Tensor | complex) Operator[Unpack[Tin], Tout][source]

Operator multiplication with tensor.

Returns lambda x: self(x*other)

__radd__(other: Tensor | complex) Operator[Unpack[Tin], tuple[Unpack[Tin]]][source]

Operator right addition.

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

__rmul__(other: Tensor | complex) Operator[Unpack[Tin], Tout][source]

Operator multiplication with tensor.

Returns lambda x: other*self(x)