elsa operators

Identity

template<typename data_t = real_t>
class elsa::Identity : public elsa::LinearOperator<real_t>

Operator representing the identity operation.

This class represents a linear operator A that is the identity, i.e. Ax = x.

Author

Matthias Wieczorek - initial code

Author

Tobias Lasser - modularization, rewrite

Template Parameters
  • data_t: data type for the domain and range of the operator, defaulting to real_t

Public Functions

Identity(const DataDescriptor &descriptor)

Constructor for the identity operator, specifying the domain (= range).

Parameters
  • [in] descriptor: DataDescriptor describing the domain and range of the operator

~Identity() override = default

default destructor

Protected Functions

Identity(const Identity<data_t>&) = default

default copy constructor, hidden from non-derived classes to prevent potential slicing

void applyImpl(const DataContainer<data_t> &x, DataContainer<data_t> &Ax) const override

apply the identity operator A to x, i.e. Ax = x

Parameters

void applyAdjointImpl(const DataContainer<data_t> &y, DataContainer<data_t> &Aty) const override

apply the adjoint of the identity operator A to y, i.e. A^ty = y

Parameters

Identity<data_t> *cloneImpl() const override

implement the polymorphic clone operation

bool isEqual(const LinearOperator<data_t> &other) const override

implement the polymorphic comparison operation

Scaling

template<typename data_t = real_t>
class elsa::Scaling : public elsa::LinearOperator<real_t>

Operator representing a scaling operation.

This class represents a linear operator A that scales the input, either by a scalar or by a diagonal scaling matrix.

Author

Matthias Wieczorek - initial code

Author

Maximilian Hornung - minor fixes

Author

Tobias Lasser - modularization, rewrite

Template Parameters
  • data_t: data type for the domain and range of the operator, defaulting to real_t

Public Functions

Scaling(const DataDescriptor &descriptor, data_t scaleFactor)

Constructor for a scalar, isotropic scaling operator.

Parameters
  • [in] descriptor: DataDescriptor describing the domain and the range of the operator

  • [in] scaleFactor: the scalar factor to scale with

Scaling(const DataDescriptor &descriptor, const DataContainer<data_t> &scaleFactors)

Constructor for a diagonal, anisotropic scaling operator.

Parameters
  • [in] descriptor: DataDescriptor describing the domain and the range of the operator

  • [in] scaleFactors: a DataContainer containing the scaling factor to be put on the diagonal

Scaling(const Scaling<data_t>&) = delete

make copy constructor deletion explicit

~Scaling() override = default

default destructor

bool isIsotropic() const

is the scaling isotropic

data_t getScaleFactor() const

returns the scale factor (throws if scaling is not isotropic)

const DataContainer<data_t> &getScaleFactors() const

returns the scale factors (throws if scaling is isotropic)

Protected Functions

void applyImpl(const DataContainer<data_t> &x, DataContainer<data_t> &Ax) const override

apply the scaling operation

void applyAdjointImpl(const DataContainer<data_t> &y, DataContainer<data_t> &Aty) const override

apply the adjoint of the scaling operation

Scaling<data_t> *cloneImpl() const override

implement the polymorphic clone operation

bool isEqual(const LinearOperator<data_t> &other) const override

implement the polymorphic comparison operation

Private Members

bool _isIsotropic

flag if the scaling is isotropic

data_t _scaleFactor

isotropic scaling factor

std::unique_ptr<const DataContainer<data_t>> _scaleFactors = {}

anisotropic scaling factors

FiniteDifferences

template<typename data_t = real_t>
class elsa::FiniteDifferences : public elsa::LinearOperator<real_t>

Operator to compute finite differences.

This class represents a linear operator D that computes finite differences, using the central, forward, or backward differences.

Author

Matthias Wieczorek - initial code

Author

Maximilian Hornung - rewrite and performance optimization

Author

Tobias Lasser - modernization

Template Parameters
  • data_t: data type for the domain and range of the operator, defaulting to real_t

Public Types

enum DiffType

supported types of finite differences

Values:

enumerator FORWARD
enumerator BACKWARD
enumerator CENTRAL

Public Functions

FiniteDifferences(const DataDescriptor &domainDescriptor, DiffType type = DiffType::FORWARD)

Constructor for FiniteDifferences over all dimensions.

This implementation uses zero padding such that it’s equal to the following matrix formulation (in 1D)

  • Dforward = full(spdiags([-e e], 0:1, n, n));

  • Dbackward = full(spdiags([-e e], -1:0, n, n));

  • Dcentral = spdiags(0.5*[-e e], [-1,1], n, n);

Parameters
  • [in] domainDescriptor: Descriptor for domain

  • [in] type: denoting the type of finite differences

Note: the descriptor for the range is automatically generated from the domain.

FiniteDifferences(const DataDescriptor &domainDescriptor, const BooleanVector_t &activeDims, DiffType type = DiffType::FORWARD)

Constructor for FiniteDifferences over selected dimensions.

This implementation uses zero padding such that it’s equal to the following matrix formulation (in 1D)

  • Dforward = full(spdiags([-e e], 0:1, n, n));

  • Dbackward = full(spdiags([-e e], -1:0, n, n));

  • Dcentral = spdiags(0.5*[-e e], [-1,1], n, n);

Parameters
  • [in] domainDescriptor: Descriptor for domain

  • [in] activeDims: Boolean vector defining which dimensions are active or not

  • [in] type: denoting the type of finite differences

Note: the descriptor for the range is automatically generated from the domain.

~FiniteDifferences() override = default

default destructor

Protected Functions

FiniteDifferences(const FiniteDifferences<data_t>&) = default

default copy constructor, hidden from non-derived classes to prevent potential slicing

void applyImpl(const DataContainer<data_t> &x, DataContainer<data_t> &Ax) const override

apply the finite differences operator

void applyAdjointImpl(const DataContainer<data_t> &y, DataContainer<data_t> &Aty) const override

apply the adjoint of the finite differences operator

FiniteDifferences<data_t> *cloneImpl() const override

implement the polymorphic clone operation

bool isEqual(const LinearOperator<data_t> &other) const override

implement the polymorphic comparison operation

Private Functions

void precomputeHelpers()

precompute some helper variables to optimize speed

template<typename FDtype>
void applyHelper(const DataContainer<data_t> &x, DataContainer<data_t> &Ax, FDtype type) const

precomputed helper for active dim counter

the actual finite differences computations (with mode as template parameter for performance)

template<typename FDtype>
void applyAdjointHelper(const DataContainer<data_t> &y, DataContainer<data_t> &Aty, FDtype type) const

the actual finite differences computations (with mode as template parameter for performance)

Private Members

DiffType _type

type of the finite differences to be computed

BooleanVector_t _activeDims

boolean vector for active dimensions when computing finite differences

IndexVector_t _coordDelta

precomputed helper for coordinate diffs

IndexVector_t _dimCounter

precomputed helper for coordinate deltas

BlockLinearOperator

template<typename data_t = real_t>
class elsa::BlockLinearOperator : public elsa::LinearOperator<real_t>

Class representing a block operator matrix.

A block linear operator represents a block operator matrix

\( B \) consisting of multiple matrices \( A_i, i=1,\ldots,n \) stacked:
  • rowwise

    \[\begin{split} B = \begin{bmatrix} A_{1}\\ A_{2}\\ \vdots\\ A_{n} \end{bmatrix} \end{split}\]

  • columnwise

    \[ B = \begin{bmatrix} A_{1} & A_{2} & \hdots & A_{n} \end{bmatrix} \]

Author

Matthias Wieczorek - initial code

Author

David Frank - rewrite

Author

Nikola Dinev - automatic descriptor generation, rewrite

Template Parameters
  • data_t: data type for the domain and range of the operator, defaulting to real_t

Public Types

enum BlockType

possible arrangements of the blocks

Values:

enumerator ROW
enumerator COL
using OperatorList = typename std::vector<std::unique_ptr<LinearOperator<data_t>>>

convenience typedef for a vector of pointers to LinearOperator

Public Functions

BlockLinearOperator(const OperatorList &ops, BlockType blockType)

Construct a BlockLinearOperator of the given BlockType from the list of operators.

The domain and range descriptors of the

BlockLinearOperator are generated automatically based on the descriptors of the operators in the list. For the block descriptor, a PartitionDescriptor is preferentially generated, if not possible a RandomBlocksDescriptor is generated instead. For the non-block descriptor the best common descriptor is chosen (see DataDescriptor::bestCommon()).
Parameters
  • [in] ops: the list of operators

  • [in] blockType: the fashion in which the operators are to be stacked

Exceptions
  • std::invalid_argument: if ops is empty

BlockLinearOperator(const DataDescriptor &domainDescriptor, const DataDescriptor &rangeDescriptor, const OperatorList &ops, BlockType blockType)

Construct a BlockLinearOperator of the given BlockType from the list of operators, and additionally manually set the domain and range descriptors of the operator.

Parameters
  • [in] domainDescriptor: descriptor of the domain of the operator

  • [in] rangeDescriptor: descriptor of the range of the operator

  • [in] ops: the list of operators

  • [in] blockType: the fashion in which the operators are to be stacked

Exceptions
  • std::invalid_argument: if the passed in descriptors are not suitable for the BlockLinearOperator

~BlockLinearOperator() override = default

default destructor

const LinearOperator<data_t> &getIthOperator(index_t i) const

return the operator corresponding to the i-th block of the matrix

index_t numberOfOps() const

return the total number of blocks

Protected Functions

BlockLinearOperator(const BlockLinearOperator &other)

protected copy constructor; used for cloning

void applyImpl(const DataContainer<data_t> &x, DataContainer<data_t> &Ax) const override

apply the block linear operator

void applyAdjointImpl(const DataContainer<data_t> &y, DataContainer<data_t> &Aty) const override

apply the adjoint of the block linear operator

BlockLinearOperator<data_t> *cloneImpl() const override

implement the polymorphic clone operation

bool isEqual(const LinearOperator<data_t> &other) const override

implement the polymorphic comparison operation

Private Members

OperatorList _operatorList

list specifying the individual operators corresponding to each block

BlockType _blockType

determines in which fashion the operators are concatenated - rowwise or columnwise

Private Static Functions

std::unique_ptr<DataDescriptor> determineDomainDescriptor(const OperatorList &operatorList, BlockType blockType)

returns the best fitting domain descriptor based on the operator list and block type

std::unique_ptr<DataDescriptor> determineRangeDescriptor(const OperatorList &operatorList, BlockType blockType)

returns the best fitting range descriptor based on the operator list and block type

std::unique_ptr<BlockDescriptor> bestBlockDescriptor(const std::vector<const DataDescriptor*>&)

finds the best fitting block descriptor, such that each block is described by the corresponding descriptor in the list